Est-il possible de désinscrire une méthode anonyme 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 me désinscrire comme ceci:
MyEvent -= MyMethod;
Mais si je m'abonne en utilisant une méthode anonyme:
MyEvent += delegate(){Console.WriteLine("I did it!");};
est-il possible de se désinscrire de cette méthode anonyme? Si c'est le cas, comment?
Réponses:
Gardez simplement une référence au délégué autour.
la source
Une technique consiste à déclarer une variable pour contenir la méthode anonyme qui serait alors disponible à l'intérieur de la méthode anonyme elle-même. Cela a fonctionné pour moi car le comportement souhaité était de se désinscrire après la gestion de l'événement.
Exemple:
la source
De mémoire, la spécification ne garantit pas explicitement le comportement dans les deux cas lorsqu'il s'agit d'équivalence de délégués créés avec des méthodes anonymes.
Si vous devez vous désinscrire, vous devez soit utiliser une méthode "normale", soit conserver le délégué ailleurs afin de pouvoir vous désinscrire avec exactement le même délégué que vous avez utilisé pour vous abonner.
la source
En 3.0 peut être raccourci à:
la source
Depuis que la fonction des fonctions locales C # 7.0 a été publiée, l'approche suggérée par J c devient vraiment soignée.
Donc, honnêtement, vous n'avez pas de fonction anonyme comme variable ici. Mais je suppose que la motivation pour l'utiliser dans votre cas peut s'appliquer aux fonctions locales.
la source
Au lieu de conserver une référence à un délégué, vous pouvez instrumenter votre classe afin de rendre la liste d'invocation de l'événement à l'appelant. Fondamentalement, vous pouvez écrire quelque chose comme ça (en supposant que MyEvent est déclaré dans MyClass):
Ainsi, vous pouvez accéder à la liste d'invocation entière depuis l'extérieur de MyClass et vous désinscrire de tout gestionnaire que vous souhaitez. Par exemple:
J'ai écrit un article complet sur cette technique ici .
la source
Type d'approche boiteuse:
Cela peut ne pas fonctionner ou être la méthode la plus efficace, mais devrait faire le travail.
la source
Si vous souhaitez pouvoir contrôler la désinscription, vous devez suivre l'itinéraire indiqué dans votre réponse acceptée. Cependant, si vous souhaitez simplement effacer les références lorsque votre classe d'abonnement est hors de portée, il existe une autre solution (légèrement compliquée) qui implique l'utilisation de références faibles. Je viens de poster une question et une réponse sur ce sujet.
la source
Une solution simple:
transmettez-lui simplement la variable eventhandle comme paramètre. Si vous avez le cas où vous ne pouvez pas accéder à la variable créée d'origine en raison du multithreading, vous pouvez utiliser ceci:
la source
MyEvent -= myEventHandlerInstance;
être 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é, vous pouvez peut-être utiliser Delegate.CreateDelegate (Type, Object target, MethodInfo methodInfo) .net considérez le délégué égal par cible et methodInfo
la source
Si le meilleur moyen est de conserver une référence sur le gestionnaire d'événements auquel vous êtes abonné, vous pouvez le faire à l'aide d'un dictionnaire.
Dans cet exemple, je dois utiliser une méthode anonyme pour inclure le paramètre mergeColumn pour un ensemble de DataGridViews.
L'utilisation de la méthode MergeColumn avec le paramètre enable défini sur true active l'événement tout en l'utilisant avec false le désactive.
la source