59 votes

L'appel d'une méthode d'extension sur une référence "nulle" (c'est-à-dire un événement sans abonné) est-il mauvais?

Mal ou pas mal?

 public static void Raise(this EventHandler handler, object sender, EventArgs args)
{
   if (handler != null)
   {
      handler(sender, args);
   }
}

// Usage:
MyButtonClicked.Raise(this, EventArgs.Empty);

// This works too! Evil?
EventHandler handler = null;
handler.Raise(this, EVentArgs.Empty);
 

Notez qu'en raison de la nature des méthodes d'extension, MyButtonClicked.Raise ne lève pas d'exception NullReferenceException si MyButtonClicked est null. (Par exemple, il n'y a pas d'écouteur pour l'événement MyButtonClicked).

Mal ou pas?

35voto

Dan Goldstein Points 8940

Pas mal. Je souhaite que les événements fonctionnent de cette façon par défaut. Quelqu'un peut-il expliquer pourquoi un événement sans abonné est nul?

14voto

jonnii Points 17046

Vous pouvez toujours déclarer vos événements comme ceci (non que je le recommande):

 public event EventHandler<EventArgs> OnClicked = delegate { };
 

De cette façon, ils ont quelque chose qui leur est assigné quand vous les appelez, ils ne lèvent donc pas d'exception de pointeur null.

Vous pouvez probablement vous débarrasser du mot clé délégué en C # 3.0 ...

9voto

alvin Points 169

N'oubliez pas d'utiliser [MethodImpl(MethodImplOptions.NoInlining)] , sinon il est possible qu'il ne soit pas thread-safe.

(Lisez cela il y a quelque temps, souvenez-vous-en, googlez et trouvez http://blog.quantumbitdesigns.com/tag/events/ )

6voto

Squirrel Points 555

Venant de java arrière-plan ce qui m'a toujours semblé étrange pour moi. Je pense que personne ne l'écoute d'un événement est parfaitement valide. Surtout quand les auditeurs sont ajoutés et supprimés de façon dynamique.

Pour moi, cela semble un de C#'s gottchas qui provoque des bugs quand les gens ne savent pas / oubliez pas de vérifier la valeur null à chaque fois.

Cacher ce détail de l'implémentation semble un bon plan, car il n'est pas d'aider la lisibilité pour vérifier les valeurs null à chaque fois. Je suis sûr que le MSFTs va dire, il y a un gain de performance non constucting cas si personne n'est à l'écoute, mais à mon humble avis, il est largement compensé par le inutile de pointeur null exceptions / réduction de la lisibilité dans la plupart des code de commerce.

Je voudrais aussi ajouter ces deux méthodes à la classe:

    public static void Raise(this EventHandler handler, object sender)
    {
        Raise(handler, sender, EventArgs.Empty);
    }

    public static void Raise<TA>(this EventHandler<TA> handler, object sender, TA args)
        where TA : EventArgs
    {
        if (handler != null)
        {
            handler(sender, args);
        }
    }

5voto

David Points 1644

Pourquoi serait-ce le mal?

Son objectif est clair: il déclenche l'événement MyButtonClicked.

Il ajoute effectivement un temps système d’appel de fonction, mais dans .NET, il sera optimisé ou de manière assez rapide.

C'est un peu trivial, mais cela résout mon plus gros problème avec C #.

Dans l’ensemble, je pense que c’est une idée fantastique et qu’elle la volera probablement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X