De désabonnement de la méthode anonyme en C#
Est-il possible de se désinscrire d'une méthode anonyme à partir d'un événement?
Si je m'abonne à un événement comme celui-ci:
void MyMethod()
{
Console.WriteLine("I did it!");
}
MyEvent += MyMethod;
Je peux vous désinscrire comme ceci:
MyEvent -= MyMethod;
Mais si je vous abonner à l'aide d'une méthode anonyme:
MyEvent += delegate(){Console.WriteLine("I did it!");};
est-il possible de vous désabonner de cette méthode anonyme? Si oui, comment?
- Comme pour expliquer pourquoi vous ne pouvez pas faire ceci: stackoverflow.com/a/25564492/23354
Vous devez vous connecter pour publier un commentaire.
Il suffit de garder une référence au délégué de autour de.
Une technique consiste à déclarer une variable pour contenir la méthode anonyme qui sera disponible à l'intérieur de la méthode anonyme lui-même. Cela a fonctionné pour moi, parce que le comportement désiré est pour vous désabonner après l'événement a été géré.
Exemple:
De la mémoire, la spécification explicite ne garantit pas le comportement de toute façon quand il s'agit de l'équivalence des délégués créé avec les méthodes anonymes.
Si vous avez besoin de vous désinscrire, vous devez soit utiliser un "normal" de la méthode ou de conserver le délégué ailleurs de sorte que vous pouvez vous désabonner avec exactement le même délégué que vous avez utilisé pour vous inscrire.
En 3.0 peut être réduit à:
Depuis C# 7.0 fonctions locales fonctionnalité a été libéré, l'approche suggéré par J c devient vraiment intéressant.
Donc, honnêtement, vous n'avez pas une fonction anonyme comme une variable ici. Mais je suppose que la motivation à utiliser dans votre cas peut être appliquée à des fonctions locales.
Au lieu de garder une référence à un délégué, vous pouvez instrument de votre classe afin de donner à la manifestation de la liste d'invocation à l'appelant. Fondamentalement, vous pouvez écrire quelque chose comme ceci (en supposant que MyEvent est déclarée à l'intérieur d'MyClass):
De sorte que vous pouvez accéder à l'ensemble de la liste d'invocation de l'extérieur de MyClass et vous désinscrire à tout gestionnaire vous le souhaitez. Par exemple:
J'ai écrit un post complet sur cette tecnique ici.
Genre de boiteux approche:
Cela peut ne pas fonctionner ou être la méthode la plus efficace, mais devrait faire le travail.
Si vous voulez être en mesure de contrôler le désabonnement vous devez alors suivre l'itinéraire indiqué dans votre réponse. Toutefois, si vous êtes juste une question, à propos de l'effacement des références lors de l'abonnement de votre classe est hors de portée, alors il y a une autre (un peu compliquée) solution qui consiste à utiliser les références faibles. J'ai juste posté un la question et la réponse sur ce sujet.
Une solution simple:
vient de passer le eventhandle variable comme paramètre à lui-même.
Événement si vous avez le cas que vous ne pouvez pas accéder à l'original créé variable en raison de multithreading, vous pouvez utiliser ceci:
MyEvent -= myEventHandlerInstance;
est exécuté? Si c'est possible, vous auriez une erreur. Mais je ne sais pas si c'est le cas.si vous voulez faire référence à un objet avec ce délégué, peut-être vous pouvez utiliser Délégué.CreateDelegate(Type, de l'Objet cible, MethodInfo methodInfo)
.net considérer le délégué est égal par cible et methodInfo
Si la meilleure façon est de garder une référence sur l'abonné gestionnaire d'événements, ce qui peut être réalisé à l'aide d'un Dictionnaire.
Dans cet exemple, je dois utiliser une méthode anonyme à inclure la mergeColumn paramètre pour un ensemble de DataGridViews.
À l'aide de la MergeColumn méthode avec le activer le paramètre est défini sur true pour activer l'événement tout en l'utilisant avec des faux désactive.