27 votes

Pourquoi *devrions-nous* utiliser EventHandler

Je déteste EventHandler. Je déteste devoir caster le sender si je veux faire quelque chose avec. Je déteste devoir créer une nouvelle classe héritant de EventArgs pour utiliser EventHandler.

On m'a toujours dit que EventHandler était la tradition et blabla... peu importe. Mais je ne trouve pas de raison pour laquelle ce dogme est toujours présent.

Y a-t-il une raison pour laquelle ce serait une mauvaise idée de créer un nouveau délégué :

délégué void EventHandler(TSender sender, T args);

Ainsi le sender sera de type sûr et je pourrais passer ce que je veux comme arguments (y compris des EventArgs personnalisés si je le souhaite).

22voto

Greg Beech Points 55270

Il y a en fait une bonne raison de requérir que le deuxième argument soit dérivé de EventArgs si votre code entièrement approuvé héberge du code tiers en partie approuvé.

Parce que le rappel au délégué de gestion des événements est fait dans le contexte du code déclencheur et non du code tiers, il est possible pour du code tiers malveillant d'ajouter une opération système privilégiée en tant que gestionnaire d'événements et ainsi éventuellement exécuter une attaque par élévation de privilèges en exécutant du code dans votre contexte entièrement approuvé que leur contexte partiellement approuvé ne pourrait pas exécuter.

Par exemple, si vous déclarez un gestionnaire de type int -> void, alors le code tiers pourrait mettre en file d'attente VotreÉvénement += Enviroment.Exit(-1) et vous faire quitter le processus involontairement. Cela causerait évidemment un problème facile à détecter, mais il existe des API beaucoup plus malveillantes qui pourraient être mises en file d'attente pour faire d'autres choses.

Lorsque la signature est (object, EventArgs) -> void, il n'y a pas d'opérations privilégiées dans le framework qui peuvent être mises en file d'attente car aucune d'entre elles n'est compatible avec cette signature. Cela fait partie de l'examen de code de sécurité dans le framework pour s'assurer de cela (malheureusement, je ne trouve pas la source où j'ai lu cela).

Donc, dans certaines circonstances, il y a des préoccupations de sécurité légitimes quant à pourquoi vous devriez utiliser le modèle standard. Si vous êtes sûr à 100% que votre code ne sera jamais utilisé dans ces circonstances, alors la directive de signature d'événement n'est pas aussi importante (à part d'autres développeurs pensant WTF), mais si cela pourrait être le cas, alors vous devriez la suivre.

6voto

Preet Sangha Points 39414

Il n'y a aucune raison de l'utiliser autre que la convention .net acceptée et tout lecteur de votre code devrait le comprendre assez facilement. Pour cela, c'est une bonne raison.

Cependant, c'est votre code et vous pouvez décider ce qui est le mieux pour vous. Bien sûr, lorsque vous interagissez avec la fcl, vous devrez le faire à leur manière en utilisant des gestionnaires d'événements.

5voto

Eamon Nerbonne Points 21663

J'utilise couramment les types Action<...> en tant que gestionnaires d'événements - si vous n'avez pas besoin d'interopérer avec un autre code (ou un designer) qui nécessite spécifiquement EventHandler, il n'y a aucune raison de l'utiliser.

2voto

Hans Passant Points 475940

Eh bien, faire tout ce casting est inhabituel, le code client sait souvent déjà qui est l'expéditeur car il a explicitement souscrit à l'événement pour un seul objet. Le partage des gestionnaires d'événements est assez rare. Si un comportement commun est souhaitable, la meilleure approche est de dériver de la classe et de remplacer la méthode OnXxxx. Vous n'avez alors plus besoin du transmetteur, vous avez this.

Cependant, résolvez votre problème de manière triviale en incluant une référence de type sécurisé à l'expéditeur dans votre classe dérivée d'EventArgs personnalisée.

1voto

Scott Stafford Points 13161

Je suis d'accord avec vous, la convention est stupide et/ou antiquée. Faites les choses correctement, avec une bonne sécurité des types et des générics.

Il arrive tout le temps que vous ayez une tâche à accomplir, et vous pouvez suivre la façon dont le dernier l'a fait, ou le faire d'une autre manière que vous pensez probablement meilleure.

Le premier choix est généralement choisi - faites-le de la même manière que le dernier, et vous ne serez pas en difficulté. Mais le deuxième choix est ce qui améliore logiciel sur le long terme. (Ou du moins ça PEUT l'améliorer, si vous avez raison que votre façon est meilleure! :) )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X