Bei einer Codeüberprüfung bin ich über dieses (vereinfachte) Codefragment zum Aufheben der Registrierung eines Ereignishandlers gestolpert:
Fire -= new MyDelegate(OnFire);
Ich dachte, dass dies die Registrierung des Ereignis-Handlers nicht aufhebt, da ein neuer Delegat erstellt wird, der noch nie registriert wurde. Aber beim Durchsuchen von MSDN fand ich mehrere Codebeispiele, die dieses Idiom verwenden.
Also habe ich ein Experiment gestartet:
internal class Program
{
public delegate void MyDelegate(string msg);
public static event MyDelegate Fire;
private static void Main(string[] args)
{
Fire += new MyDelegate(OnFire);
Fire += new MyDelegate(OnFire);
Fire("Hello 1");
Fire -= new MyDelegate(OnFire);
Fire("Hello 2");
Fire -= new MyDelegate(OnFire);
Fire("Hello 3");
}
private static void OnFire(string msg)
{
Console.WriteLine("OnFire: {0}", msg);
}
}
Zu meiner Überraschung geschah dann Folgendes:
Fire("Hello 1");
erzeugte wie erwartet zwei Meldungen.Fire("Hello 2");
eine Nachricht produziert!
Dies hat mich davon überzeugt, dass die Abmeldungnew
Delegierte arbeiten!Fire("Hello 3");
warf eineNullReferenceException
.
Das Debuggen des Codes ergab, dassFire
esnull
nachdem Sie das Ereignis abgemeldet haben.
Ich weiß, dass der Compiler für Event-Handler und Delegate eine Menge Code hinter der Szene generiert. Aber ich verstehe immer noch nicht, warum meine Argumentation falsch ist.
Was übersehe ich?
Zusätzliche Frage: Aus der Tatsache, dass Fire
es null
wenn keine Ereignisse registriert werden, schließe ich daraus, dass überall dort, wo ein Ereignis ausgelöst wird, eine Prüfung gegen null
erforderlich ist.