C#, Comment le trouver, si un événement est accroché
Je veux être en mesure de savoir si un événement est branché ou non. J'ai regardé autour, mais j'ai seulement trouvé des solutions qui a impliqué la modification de la structure interne de l'objet qui contient l'événement. Je ne veux pas faire ça.
Voici un code de test que j'ai pensé de travail:
//Create a new event handler that takes in the function I want to execute when the event fires
EventHandler myEventHandler = new EventHandler(myObject_SomeEvent);
//Get "p1" number events that got hooked up to myEventHandler
int p1 = myEventHandler.GetInvocationList().Length;
//Now actually hook an event up
myObject.SomeEvent += m_myEventHandler;
//Re check "p2" number of events hooked up to myEventHandler
int p2 = myEventHandler.GetInvocationList().Length;
Unfort ci-dessus est tout à fait tort. Je pensais qu'en quelque sorte les "invocationList" dans myEventHandler serait automatiquement mise à jour lorsque j'ai accroché un événement à elle. Mais non, ce n'est pas le cas. La longueur de cette revient toujours comme un.
Est-il de toute façon à déterminer ce à partir de l'extérieur de l'objet qui contient l'événement?
Vous devez vous connecter pour publier un commentaire.
Il y a une subtile illusion présenté par le C#
event
mot-clé et c'est qu'un événement a une liste d'invocation.Si vous déclarez l'événement en utilisant le C#
event
mot-clé, le compilateur va générer un délégué privé dans votre classe, et de le gérer pour vous. Chaque fois que vous vous inscrire à l'événement, l'généré par le compilateuradd
méthode est invoquée, qui ajoute le gestionnaire d'événement pour le délégué de la liste d'invocation. Il n'y a pas une liste d'invocation pour l'événement.Ainsi, le seul moyen d'obtenir le délégué de la liste d'invocation est de préférence:
Voici un exemple montrant la dernière technique.
Si l'objet est spécifié, l'événement de mot-clé, les seules choses que vous pouvez faire à ajouter (
+=
) et supprimer (-=
) gestionnaires, rien de plus.Je crois que la comparaison de l'invocation de la liste de la longueur de travail, mais vous devez être en exploitation à l'intérieur de l'objet pour obtenir à elle.
Aussi, gardez à l'esprit que la
+=
et-=
opérateurs de renvoyer un nouvel objet d'événement; ils ne sont pas en modifier un existant.Pourquoi voulez-vous savoir si un événement particulier est branché? Est-ce pour éviter l'enregistrement plusieurs fois?
Si donc, l'astuce est de supprimer le gestionnaire d'abord (
-=
) que la suppression d'un gestionnaire qui n'est pas juridique, et ne fait rien. Par exemple:-=
va supprimer un, je ne sais pas de toute façon de travailler qui, étant donné qu'ils sont tous égaux.Il peut être fait, mais il faut un certain hackery... comme mentionné ci-dessus, le compilateur génère la mise en œuvre de l'événement, y compris son champ de stockage. La réflexion permet de récupérer la sauvegarde de champ par son nom, et une fois que vous y avez accès, vous pouvez appeler
GetInvocationList()
même si vous êtes à l'extérieur de la classe elle-même.Depuis que vous demandez à utiliser la réflexion pour obtenir l'événement, par le nom, je suppose que vous êtes aussi à l'aide de la réflexion pour obtenir le Type de nom, je suis en fouettant jusqu'à un exemple qui va vous montrer comment le faire.
EventHandler
n'est pas assez générale, je suggère d'utiliserreturn (Delegate)eventField.GetValue(classInstance)
Vous devriez être en mesure d'obtenir la liste d'invocation via l ' "événement". En gros, il sera quelque chose comme..