Dans une revue de code, je suis tombé sur ce fragment de code (simplifié) pour désenregistrer un gestionnaire d'événements:Comment désenregistrer correctement un gestionnaire d'événements
Fire -= new MyDelegate(OnFire);
Je pensais que cela ne désenregistrer pas le gestionnaire d'événements, car il crée un nouveau délégué qui n'avait jamais été enregistré auparavant. Mais en cherchant MSDN j'ai trouvé plusieurs exemples de code qui utilisent cet idiome.
Alors j'ai 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, ce qui suit est arrivé:
Fire("Hello 1");
a produit deux messages, comme prévu.Fire("Hello 2");
a produit un message!
Cela m'a convaincu que la désinscriptionnew
délégués fonctionne!Fire("Hello 3");
a lancé unNullReferenceException
.
Le débogage du code a montré queFire
estnull
après la désinscription de l'événement.
Je sais que pour les gestionnaires d'événements et les délégués, le compilateur génère beaucoup de code derrière la scène. Mais je ne comprends toujours pas pourquoi mon raisonnement est faux.
Qu'est-ce qui me manque?
question supplémentaire: le fait que Fire
est null
quand il n'y a pas d'événements enregistrés, je conclus que partout un événement est déclenché, un chèque contre null
est nécessaire.
Yep. Pour compléter: cela me confondre pendant un certain temps aussi, d'autant plus que dans C# vous pouvez faire Fire + = new MyDelegate (OnFire) ou Fire + = OnFire; Ce dernier semble être plus simple, mais n'est que du sucre syntaxique pour le premier. –
@Nicholas Piasecki: Merci; J'ai mis à jour ma réponse pour noter que (plutôt utile) sténographie. –
Il peut être utile de noter que l'ajout d'un délégué de multidiffusion et sa désinscription ultérieure peuvent donner des résultats incorrects si l'une des méthodes de ce délégué de multidiffusion est également souscrite et désabonnée individuellement. – supercat