Je ne vois pas d'avantages à utiliser des événements par rapport aux délégués, à part être du sucre syntaxique. Peut-être que je ne comprends pas, mais il semble que l'événement n'est qu'un espace réservé pour le délégué.
Pourriez-vous m'expliquer les différences et quand les utiliser? Quels sont les avantages et les inconvénients? Notre code est fortement ancré dans les événements, et je veux aller au fond des choses.
Quand utiliseriez-vous des délégués lors d'événements et vice versa? Veuillez indiquer votre expérience du monde réel avec les deux, par exemple dans le code de production.
Réponses:
Du point de vue technique, d'autres réponses ont abordé les différences.
D'un point de vue sémantique, les événements sont des actions déclenchées par un objet lorsque certaines conditions sont remplies. Par exemple, ma classe Stock a une propriété appelée Limite et déclenche un événement lorsque le cours des actions atteint la limite. Cette notification se fait via un événement. Que quelqu'un se soucie réellement de cet événement et y adhère est au-delà de la préoccupation de la classe des propriétaires.
Un délégué est un terme plus générique pour décrire une construction similaire à un pointeur en termes C / C ++. Tous les délégués dans .Net sont des délégués multicast. D'un point de vue sémantique, ils sont généralement utilisés comme une sorte d'entrée. En particulier, ils constituent un moyen idéal de mettre en œuvre le modèle de stratégie . Par exemple, si je souhaite trier une liste d'objets, je peux fournir une stratégie de comparaison à la méthode pour indiquer à l'implémentation comment comparer deux objets.
J'ai utilisé les deux méthodes dans le code de production. Des tonnes de mes objets de données avertissent lorsque certaines propriétés sont remplies. Exemple le plus basique, chaque fois qu'une propriété change, un événement PropertyChanged est déclenché (voir interface INotifyPropertyChanged). J'ai utilisé des délégués dans le code pour fournir différentes stratégies de transformation de certains objets en chaîne. Cet exemple particulier était une liste ToString () glorifiée d'implémentations pour un type d'objet particulier pour l'afficher aux utilisateurs.
la source
Le mot clé
event
est un modificateur de portée pour les délégués multicast. Les différences pratiques entre cela et la simple déclaration d'un délégué de multidiffusion sont les suivantes:event
dans une interface.public event
).Par intérêt, vous pouvez appliquer
+
et-
à des délégués de multidiffusion, et c'est la base de la syntaxe+=
et-=
pour l'affectation de combinaison de délégués à des événements. Ces trois extraits sont équivalents:Exemple deux, illustrant à la fois l'assignation directe et l'assignation combinée.
Exemple trois: syntaxe plus familière. Vous connaissez probablement l'attribution de null pour supprimer tous les gestionnaires.
Comme les propriétés, les événements ont une syntaxe complète que personne n'utilise jamais. Ce:
... fait exactement la même chose:
Les méthodes d'ajout et de suppression sont plus visibles dans la syntaxe plutôt stilted que VB.NET utilise (pas de surcharge d'opérateur).
la source
Les événements sont du sucre syntaxique. Ils sont délicieux. Quand je vois un événement, je sais quoi faire. Quand je vois un délégué, je ne suis pas si sûr.
La combinaison d'événements avec des interfaces (plus de sucre) en fait une collation alléchante. Les délégués et les classes abstraites virtuelles pures sont beaucoup moins appétissants.
la source
Les événements sont marqués comme tels dans les métadonnées. Cela permet à des éléments tels que les concepteurs Windows Forms ou ASP.NET de distinguer les événements de simples propriétés de type délégué et de leur fournir une prise en charge appropriée (en les affichant spécifiquement dans l'onglet Événements de la fenêtre Propriétés).
Une autre différence par rapport à une propriété de type délégué est que les utilisateurs peuvent uniquement ajouter et supprimer des gestionnaires d'événements, alors qu'avec une propriété de type délégué, ils peuvent définir la valeur:
Cela aide à isoler les abonnés à l'événement: je peux ajouter mon gestionnaire à un événement, et vous pouvez ajouter votre gestionnaire au même événement, et vous n'écraserez pas accidentellement mon gestionnaire.
la source
Bien que les événements soient généralement mis en œuvre avec des délégués de multidiffusion, il n'est pas nécessaire qu'ils soient utilisés de cette manière. Si une classe expose un événement, cela signifie que la classe expose deux méthodes. Leurs significations sont, en substance:
Le moyen le plus courant pour une classe de gérer un événement qu'elle expose est de définir un délégué de multidiffusion et d'ajouter / supprimer tous les délégués qui sont passés aux méthodes ci-dessus, mais il n'est pas nécessaire qu'elles fonctionnent de cette façon. Malheureusement, l'architecture d'événement ne parvient pas à faire certaines choses qui auraient rendu les approches alternatives beaucoup plus propres (par exemple, demander à la méthode d'abonnement de renvoyer un MethodInvoker, qui serait conservé par l'abonné; pour désabonner un événement, appelez simplement la méthode retournée). sont de loin l'approche la plus courante.
la source
pour comprendre les différences, vous pouvez regarder ces 2 exemples
Exemple avec des délégués (Action dans ce cas qui est une sorte de délégué qui ne retourne pas de valeur)
pour utiliser le délégué, vous devez faire quelque chose comme ça
ce code fonctionne bien mais vous pourriez avoir quelques points faibles.
Par exemple si j'écris ceci
avec la dernière ligne de code, j'avais remplacé les comportements précédents juste avec un manquant
+
(j'ai utilisé à la+
place de+=
)Un autre point faible est que chaque classe qui utilise votre
Animal
classe peut se leverRaiseEvent
simplement en l'appelantanimal.RaiseEvent()
.Pour éviter ces points faibles, vous pouvez utiliser
events
en c #.Votre classe d'animaux changera de cette façon
pour appeler des événements
Différences:
Remarques
EventHandler est déclaré comme le délégué suivant:
il prend un expéditeur (de type Object) et des arguments d'événement. L'expéditeur est nul s'il provient de méthodes statiques.
Vous pouvez également utiliser à la
EventHAndler
place cet exemple qui utiliseEventHandler<ArgsSpecial>
référez-vous ici pour la documentation sur EventHandler
la source
Lorsque je conçois mes propres API, je définis des délégués qui sont passés en paramètres aux méthodes ou aux constructeurs de classes:
Predicate
etAction
sont passés aux classes de collection génériques .Net)Ces délégués sont généralement non optionnels au moment de l'exécution (c'est - à-dire qu'ils ne doivent pas l'être
null
).J'ai tendance à ne pas utiliser d'événements; mais là où j'utilise des événements, je les utilise pour signaler éventuellement des événements à zéro, un ou plusieurs clients qui pourraient être intéressés, c'est-à-dire quand il est logique qu'une classe (par exemple la
System.Windows.Form
classe) existe et s'exécute, qu'un client ait ou non a ajouté un gestionnaire d'événements à son événement (par exemple, l'événement «mouse down» du formulaire existe, mais il est facultatif si un client externe est intéressé par l'installation d'un gestionnaire d'événements sur cet événement).la source
Bien que je n'ai aucune raison technique à cela, j'utilise des événements dans le code de style UI, en d'autres termes, dans les niveaux supérieurs du code, et j'utilise des délégués pour une logique qui approfondit le code. Comme je l'ai dit, vous pouvez utiliser l'un ou l'autre, mais je trouve que ce modèle d'utilisation est logique, si rien d'autre, il aide à documenter les types de rappels et leur hiérarchie également.
Edit: Je pense que la différence dans les modèles d'utilisation que j'ai serait que, je trouve parfaitement acceptable d'ignorer les événements, ce sont des hooks / stubs, si vous avez besoin de connaître l'événement, écoutez-les, si vous ne vous souciez pas de l'événement ignore tout simplement. C'est pourquoi je les utilise pour l'interface utilisateur, un style d'événement Javascript / Browser. Cependant, lorsque j'ai un délégué, je m'attends VRAIMENT à ce que quelqu'un gère la tâche du délégué et lance une exception s'il n'est pas géré.
la source
La différence entre les événements et les délégués est beaucoup plus petite que je ne le pensais. Je viens de publier une vidéo YouTube super courte sur le sujet: https://www.youtube.com/watch?v=el-kKK-7SBU
J'espère que cela t'aides!
la source
la source