2009-08-27 9 views
8

Je suis confus par la syntaxe de suppression des gestionnaires d'événements en C#.Syntaxe de suppression d'événement C#

Something += new MyHandler(HandleSomething); // add 
Something -= new MyHandler(HandleSomething); // remove 

Le « nouveau » crée un nouvel objet sur chaque ligne, de sorte que vous ajoutez un objet puis demandez de supprimer un objet différent.

Que se passe-t-il vraiment sous les couvertures pour que cela fonctionne?
Ce n'est pas évident à cause de la syntaxe.

+3

La suppression d'un objet recherche dans la liste des délégués un objet correspondant à la cible et à la méthode de l'objet donné, puis supprime ce dernier. –

+0

vous ne devez pas utiliser le nouveau MyHandler, c'est juste un emballage pour un délégué. –

+0

Les réponses à cette discussion: http://stackoverflow.com/questions/1178725/how-to-unset-event ont aussi quelques discussions sur le sujet. – JeffH

Répondre

19

Le + = et les - = sont des raccourcis syntaxe intégrée dans les méthodes internes nommé Ajouter() et remove(), qui ajouter ou supprimer un pointeur vers une liste liée interne de délégués que le délégué a comme un champ privé. Lorsque vous exécutez Remove, il commence en tête de la liste chaînée et examine chaque délégué de la liste un à la fois jusqu'à ce qu'il en trouve un qui soit "égal" à celui que vous avez passé à la méthode Remove(). (En utilisant - = syntaxe)

Ensuite, il supprime que l'on de la liste chaînée, et les correctifs de la liste liée à retenir est la connectivité ...

Dans ce contexte, la méthode « égal » (pour un délégué()) est substitué de sorte qu'il ne compare que la cible du délégué, et le methodPtr, qui sera le même même si vous avez créé un nouveau délégué à passer à Supprimer ...

-1

Vous pouvez considérer les événements comme des méthodes de substitution pour la logique déléguée qui s'exécute lorsque l'événement est déclenché. Un seul événement peut avoir plusieurs abonnés (multi-cast), donc la syntaxe + = et - = est la façon dont un seul gestionnaire d'événements est attaché ou supprimé. Le simple fait d'assigner réinitialiserait les abonnements de l'événement, ce qui pourrait causer des effets secondaires indésirables.

EDIT: this link explique plus sur le concours complet en C#

+1

raison de la downvote s'il vous plaît? –

+0

Pourquoi le vote à la baisse? Cela semble être une réponse parfaitement valide. –

+0

En reformulant la question de l'OP: "Pourquoi pouvons-nous + = un nouvel objet et - = un nouvel objet complètement différent et obtenir l'effet désiré?" Josh E ne répond pas * pourquoi * nous pouvons joindre 'a' et supprimer 'b' où 'a' et 'b' sont des instances différentes et obtiennent toujours ce que nous voulons. – JeffH

7

Le "nouveau MyHandler" est en fait redondant. Vous pouvez simplement faire

Something += HandleSomething; // add 
Something -= HandleSomething; // remove 

Tous les événements en C# sont délégués multicast, donc le + = et - = syntaxe indique que vous ajoutez/la suppression d'un délégué à la liste des délégués qui seront appelés. Pour ce qui se passe dans les coulisses, la meilleure explication que j'ai trouvée est Jon Skeet's.

+0

C'est en fait la même chose que l'exemple fourni, bien que le nouveau C# ajoute cela pour vous. – Dykam

+0

Vous pouvez laisser le nouveau, mais si vous laissez Visual Studio le remplir pour vous en tapant: "Quelque chose + =" puis , le code généré automatiquement le complétera comme ceci: "Quelque chose + = new MyHandler (HandleSomething) " L'OP demande ce qui se passe sous le capot pour que la nouvelle façon fonctionne. – JeffH

+0

Ouais j'ai fini par être appelé et n'ai pas eu assez de temps pour une réponse complète. Les deux syntaxes sont équivalentes, le compilateur infère le délégué et ajoute une nouvelle instance à la liste de multidiffusion. Même lors de la suppression, la syntaxe "new EventHandler()" fonctionne car elle regarde la signature de la cible et de la méthode et non une référence d'objet spécifique. – womp