2009-10-02 8 views

Répondre

14

oui, un événement auquel personne n'est inscrit est nul. La méthode standard des événements de tir est:

event EventHandler MyEvent; 

private void FireMyEvent(EventArgs e) { 
    var handler = MyEvent; 
    if (handler != null) 
     handler(this, e); 
} 

Eric Lippert a écrit un fantastique article pourquoi ce modèle est la façon « correcte » des événements de tir

+0

Thanx pour le lien. en fait une réponse complète. +1 –

+0

du lien: Pourquoi la temp? La variable temporaire vérifie que la fonction est "thread-safe".Si les gestionnaires de l'événement sont en cours de modification sur un autre thread, il est possible que Foo soit non nul au point de vérification, puis défini sur null sur un thread différent, puis l'invocation se déclenche. –

+0

ici temp est gestionnaire –

1

Vérifier null.

if (Object.Event != null) Object.Event(); 

HTH Alex

3

Dans .NET, les événements sont (par défaut) traitées comme délégués de multidiffusion. Cela signifie que tant que vous n'aurez pas affecté le premier gestionnaire d'événements à l'événement, la référence d'événement sera null.

Cela a conduit à la manière typique d'élever un être de l'événement:

public event EventHandler Event; 

protected virtual void OnEvent(EventArgs e) 
{ 
    EventHandler @event = Event; // Copy immutable delegate for thread safety. 
    if(@event != null) // Check for null. 
     @event(e); // Raise event. 
} 
+0

Il est préférable de copier l'événement dans une variable temporaire pour éviter les conditions de course – thecoop

1

Si personne n'a souscrit à l'événement, l'objet événement est null. Il est une pratique courante d'utiliser une méthode OnEvent -comme, par exemple (en supposant que votre événement est appelé MyEvent):

public event EventHandler<MyEventArgs> MyEvent; 

void OnMyEvent(MyEventArgs args) { 
    if(MyEvent != null) MyEvent(this, args); 
} 

Lorsque vous devez soulever l'événement, vous appelez simplement la méthode OnMyEvent.

0

La solution la plus simple à ce problème est de déclarer l'événement:

public event EventHandlerType MyEvent = delegate { }; 

En d'autres termes, ajouter = delegate { }; à la fin.

Vous n'avez plus besoin d'écrire une charge de courrier indésirable chaque fois que vous déclenchez l'événement.

+0

Alors, pouvons-nous définir une référence d'événement à null ?? Si oui, il vaut mieux vérifier les valeurs nulles. –

+0

Le code des autres classes ne peut pas attribuer une nouvelle valeur à un membre déclaré comme 'event'. Ils peuvent seulement utiliser '+ =' et '- ='. Ils ne peuvent pas supprimer le délégué vide. –

5

Oui. S'il n'y a aucun abonné, l'événement sera null et vous obtiendrez une exception NullReferenceException lorsque vous l'appelez. La bonne façon de faire le chèque est comme thecoop a dit, mais il y a un simple « raccourci »:

public event EventHandler Event = delegate {}; 

Cela provoque l'événement pour un abonné par défaut qui ne fait rien, et ne sera donc pas jeter une exception si il y a des abonnés. Il y a un légère surcharge de performance de de faire cela, mais cela supprime le besoin de vérifier les nulls.

+1

voir ceci: http://stackoverflow.com/questions/170907/is-there-a-downside-to-adding-an-anonymous-empty-delegate-on-event-declaration pour les considérations de performance à utiliser des délégués vides. –

1

Juste pour ajouter, vous pouvez également utiliser des méthodes d'extension.

 public static void RaiseSafe<T>(this EventHandler<T> eventHandler, object sender, T args) 
     where T : EventArgs 
    { 
     if (eventHandler != null) 
      eventHandler(sender, args); 
    } 

Et l'utiliser comme ceci:

MyEvent.RaiseSafe(this,new EventArgs()); 
+0

Dans ce cas, la variable temporaire est redondante, car le fait de passer le gestionnaire d'événements à la méthode élimine la condition de concurrence. La vérification null est toujours nécessaire cependant. –

+0

Des acclamations intéressantes. –

Questions connexes