Dans une revue de code, je suis tombé sur ceci (simplifié) fragment de code pour annuler l'inscription d'un gestionnaire d'événement:
Fire -= new MyDelegate(OnFire);
Je pensais que cela n'a pas d'annuler l'inscription du gestionnaire d'événements, car il crée un nouveau délégué qui n'avait jamais été enregistré auparavant. Mais la recherche de MSDN, j'ai trouvé plusieurs exemples de code qui utilisent cet idiome.
J'ai donc commencé une expérience:
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);
}
}
À ma grande surprise, le suivant s'est produit:
-
Fire("Hello 1");
produit deux messages, comme prévu. -
Fire("Hello 2");
produit un message!
Cela m'a convaincu que l'annulation de l'inscriptionnew
des délégués des travaux! -
Fire("Hello 3");
jeta unNullReferenceException
.
Débogage du code ont montré queFire
estnull
après l'annulation de l'enregistrement de l'événement.
Je sais que pour les gestionnaires d'événements et de déléguer, le compilateur génère beaucoup de code derrière la scène. Mais je ne comprends toujours pas pourquoi mon raisonnement est faux.
Ce qui me manque?
Question supplémentaire: le fait qu' Fire
est null
quand il n'y a pas d'événements enregistrés, je conclus que, partout où un événement est déclenché, un chèque à l'encontre null
est requis.