Quelles sont les différences entre les délégués et les événements?
Quelles sont les différences entre les délégués et les événements? Ne pas contenir des références à des fonctions qui peuvent être exécutées?
codeproject.com/KB/cs/events.aspx
c'est ce qui explique avec l'exemple ont un look unitygeek.com/delegates-events-unity
c'est ce qui explique avec l'exemple ont un look unitygeek.com/delegates-events-unity
OriginalL'auteur Sean Chambers | 2008-08-26
Vous devez vous connecter pour publier un commentaire.
Un Événement déclaration ajoute une couche d'abstraction et de protection sur le délégué instance. Cette protection empêche les clients de l'délégué de la réinitialisation du délégué et de sa liste d'invocation et ne permet l'ajout ou la suppression de cibles à partir de la liste d'invocation.
.... Et de la protection de l'instance de délégué variable
Pas tout à fait vrai. Vous pouvez déclarer un événement sans un backend instance de délégué. En c#, vous pouvez mettre en place un événement de façon explicite et utiliser un autre backend de la structure de données de votre choix.
pouvez-vous donner un exemple pour expliquer sa?
OriginalL'auteur mmcdole
En plus de la syntaxe et de propriétés fonctionnelles, il y a aussi un semantical différence.
Délégués sont, sur le plan conceptuel, les modèles de fonction; c'est, ils expriment un contrat d'une fonction doit respecter pour être considéré comme du "type" de la délégué.
Événements représentent ... eh bien, les événements. Ils sont destinés à alerter quelqu'un quand il se passe quelque chose et oui, ils adhèrent à un délégué définition, mais ils ne sont pas la même chose.
Même si ils ont été exactement la même chose (du point de vue syntaxique et dans le code IL), il y aura toujours de la semantical différence. En général, je préfère avoir deux noms différents pour les deux concepts différents, même si ils sont utilisés de la même manière (ce qui ne signifie pas que je voudrais avoir le même code deux fois).
De la sorte, peut-on dire qu'un événement est un "spécial" type d'un délégué?
OriginalL'auteur Jorge Córdoba
De comprendre les différences, vous pouvez regarder cette 2 exemples
Exemple avec les Délégués (dans ce cas, une Action - qui est une sorte de délégué qui ne retourne pas une valeur)
À utiliser le délégué, vous devriez faire quelque chose comme ceci:
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'ai annulé la précédente comportements avec un manque
+
(j'ai utilisé=
au lieu de+=
)Un autre point faible est que chaque classe qui utilise votre
Animal
classe peut souleverRaiseEvent
juste de l'appeleranimal.RaiseEvent()
.Pour éviter ces points faibles, vous pouvez utiliser
events
en c#.Votre Animal de la classe va changer de cette façon:
à des événements d'appel
Différences:
Notes:
EventHandler est déclaré en tant que délégué suivant:
il faut un émetteur (de type d'Objet) et les arguments d'événement. L'expéditeur est null si il s'agit de méthodes statiques.
Cet exemple, qui utilise
EventHandler<ArgsSpecial>
, peut également être écrit à l'aide deEventHandler
à la place.Reportez-vous ici de la documentation sur ce Gestionnaire
RaiseEvent
tant qu'une méthode d'appel dispose d'un accès à une instance deanimal
dans le code qui utilise l'événement?Les événements ne peut être augmenté, passant à l'intérieur de la classe, peut-être que j'ai pas été clair en expliquant que. Avec les événements, vous pouvez appeler la fonction qui déclenchent l'événement (l'encapsulation), mais il ne peut être passé de l'intérieur de la classe qui la définit. Permettez-moi de savoir si je ne suis pas clair.
Grande réponse bourgeon! Maintenir le bon travail 🙂
"Les événements ne peuvent pas être directement affectés." Sauf si je vous comprends mal, ce n'est pas vrai. Voici un exemple: gist.github.com/Chiel92/36bb3a2d2ac7dd511b96
Tu veux dire que même si l'événement est déclaré en tant que public, je ne peux toujours pas faire
animal.Run(this, new ArgsSpecial("Run faster");
?OriginalL'auteur faby
Voici un bon lien pour consulter.
http://csharpindepth.com/Articles/Chapter2/Events.aspx
Brièvement, le tenir à l'écart de l'article - les Événements sont l'encapsulation sur les délégués.
Citation de l'article:
C'est plus une préoccupation théorique que rien, mais FWIW, je me sentais comme une "Option 1 est mauvais parce que nous n'aimons pas les variables publiques" argument pourrait utiliser un peu plus de précisions. S'il le dit parce que c'est "mauvais OOP pratique", techniquement un
public Delegate
variable serait d'exposer les "données", mais, au meilleur de ma connaissance de la programmation orientée objet n'a jamais évoqué une quelconque des concepts tout à fait comme unDelegate
(c'est pas un "objet", ni un "message"), et .NET vraiment à peine traite des délégués à l'instar des données de toute façon.Mais j'aimerais aussi vous donner des conseils pratiques, si vous êtes dans une situation où vous voulez vous assurer qu'il n'y a qu'un seul gestionnaire, de faire votre propre
AddXXXHandler
méthodes avec unprivate Delegate
variable peut être une bonne option. Dans ce cas, vous pouvez vérifier pour voir si un gestionnaire est déjà défini, et de réagir de façon appropriée. Cela peut également être une bonne configuration si vous avez besoin de l'objet de la tenue de laDelegate
pour être en mesure d'effacer tous les gestionnaires (event
ne vous donne aucun moyen pour ce faire).OriginalL'auteur vibhu
REMARQUE: Si vous avez accès à C# 5.0 Unleashed, lisez la section "Limitations sur la Plaine des Délégués" dans le Chapitre 18 intitulé "Événements" pour mieux comprendre les différences entre les deux.
Il m'aide toujours d'avoir un simple, un exemple concret. Voici donc un pour la communauté. J'ai d'abord montrer comment vous pouvez utiliser délégués seuls à faire ce que les Événements de le faire pour nous. Ensuite, je montre comment la même solution serait de travailler avec une instance de
EventHandler
. Et puis je vais expliquer pourquoi nous ne voulons PAS faire ce que j'explique dans le premier exemple. Ce message a été inspiré par un article par John Skeet.Exemple 1: à l'Aide de public délégué
Supposons que j'ai une application WinForms avec une seule zone de liste déroulante. La liste déroulante est lié à un
List<Person>
. Où la Personne a des propriétés de l'Id, le Nom, le Surnom, couleur des cheveux. Sur le formulaire principal est une coutume de contrôle de l'utilisateur qui affiche les propriétés de cette personne. Quand quelqu'un choisit une personne dans la liste déroulante les étiquettes dans le contrôle de l'utilisateur mise à jour pour afficher les propriétés de la personne sélectionnée.Ici est de savoir comment cela fonctionne. Nous avons trois fichiers que nous aider à mettre cela ensemble:
Voici le code correspondant à chacune des catégories:
Voici notre contrôle utilisateur:
Enfin, nous avons le code suivant dans notre Form1.cs. Ici, nous appelons OnPersonChanged, qui appelle tout le code souscrit au délégué.
Ok. Donc, c'est comment vous obtenez ce travail sans l'aide d'événements et juste à l'aide de délégués. Nous venons de mettre un public délégué dans une classe -- vous pouvez le rendre statique ou un singleton, ou quoi que ce soit. Grand.
MAIS, MAIS, MAIS, nous ne voulons pas faire ce que je viens de décrire ci-dessus. Parce que les domaines publics sont mauvais pour de très nombreuses raisons. Alors, quelles sont nos options? Comme John Skeet décrit, voici nos options:
PersonChangedDel = null
, effaçant tous les autres abonnements. L'autre problème qui demeure ici est que, puisque les utilisateurs ont accès à l'délégué, ils peuvent invoquer les cibles dans la liste d'invocation -- nous ne voulons pas que les utilisateurs externes ayant accès pour élever nos événements.Cette troisième option est essentiellement ce qu'un événement nous donne. Lors de la déclaration d'un Gestionnaire d'événements, il nous donne accès à un délégué -- pas publiquement, non pas comme une propriété, mais comme cette chose que nous appelons un événement qui a juste à ajouter/supprimer des accesseurs.
Voyons ce que le même programme ressemble, mais maintenant à l'aide d'un Événement à la place du public délégué (j'ai aussi changé notre Médiateur à un singleton):
Exemple 2: Avec le Gestionnaire d'événements au lieu d'un public délégué
Médiateur:
Notez que si vous F12 sur le Gestionnaire d'événements, il va vous montrer la définition est juste un générique-identifiés délégué, avec le supplément de "l'expéditeur" objet:
Le Contrôle De L'Utilisateur:
Enfin, voici la Form1.cs code:
Parce que le Gestionnaire veut et EventArgs en tant que paramètre, j'ai créé cette classe avec juste une propriété unique dans elle:
J'espère que ça vous montre un peu pourquoi nous avons des événements et comment ils sont différents -, mais fonctionnellement le même-en tant que délégués.
The other problem that remains here is that since the users have access to the delegate, they can invoke the targets in the invocation list -- we don't want external users having access to when to raise our events
. Dans la version la plus récente de laMediator
, vous pouvez toujours appeler laOnPersonChange
chaque fois que vous avez une référence à l'singleton. Peut-être que vous devriez mentionner que leMediator
approche n'empêche pas que certains comportements, et se rapproche plus d'un événement de bus.OriginalL'auteur Trevor
Vous pouvez également utiliser les événements dans l'interface de déclarations, pas tellement pour les délégués.
Que voulez-vous dire exactement? Vous pouvez avoir
Action a { get; set; }
à l'intérieur d'une définition de l'interface.OriginalL'auteur Paul Hill
Ce qu'est un grand malentendu entre les événements et les participants!!! Un délégué spécifie un TYPE (par exemple une
class
, ou uninterface
n'), tandis qu'un événement est juste une sorte de MEMBRE (comme les champs, propriétés, etc). Et, comme n'importe quel autre type de membre d'un événement a aussi un type. Pourtant, dans le cas d'un événement, le type de l'événement doit être spécifiée par un délégué. Par exemple, vous NE pouvez pas déclarer un événement d'un type défini par une interface.Conclusion, on peut effectuer les opérations suivantes Observation: le type d'événement DOIT être définie par un délégué. C'est le principal lien entre un événement et un délégué et est décrite dans la section II.18 la Définition des événements de ECMA-335 (CLI) de Partitions I à VI:
Cependant, ce fait n'implique PAS qu'un événement utilise un support en champ de délégué. En vérité, un événement peut utiliser un champ de stockage de données différents type de structure de votre choix. Si vous implémentez un événement explicitement en C#, vous êtes libre de choisir la façon dont vous stockez les gestionnaires d'événements (notez que gestionnaires d'événements sont des instances de la type de l'événement, qui à son tour est obligatoirement un type délégué---à partir de la précédente Observation). Mais, vous pouvez stocker ces gestionnaires d'événements (qui sont des instances déléguées) dans une structure de données comme un
List
ou unDictionary
ou tout autre chose, ou même dans un support en champ de délégué. Mais n'oubliez pas qu'il n'est PAS obligatoire que vous utilisez un champ de délégué.OriginalL'auteur Miguel Gamboa
Un événement .net est désigné combinaison d'une méthode Ajouter et de Supprimer la méthode, les deux s'attendre à quelque type particulier de délégué. C# et vb.net peut générer automatiquement le code pour l'ajouter et supprimer des méthodes qui permettront de définir un délégué à la tenue de l'événement abonnements, et ajouter/supprimer le passé dans delegagte vers/à partir de cet abonnement délégué. VB.net permettra également de générer automatiquement le code (avec le RaiseEvent déclaration) pour appeler la liste d'abonnement si et seulement si elle est non vide; pour une raison quelconque, C# ne génère pas le dernier.
Noter que, s'il est commun pour gérer les abonnements d'événements à l'aide d'un délégué multicast, qui n'est pas le seul moyen de le faire. À partir d'un point de vue, un événement abonné a besoin de savoir comment permettre à un objet de savoir, il veut recevoir des événements, mais il n'a pas besoin de connaître le mécanisme de l'editeur s'engage à utiliser pour augmenter les événements. Notez également que tandis que celui qui a défini l'événement structure de données dans .net apparemment pensé qu'il devrait être un moyen de les élever, ni C# ni vb.net fait usage de cette fonctionnalité.
OriginalL'auteur supercat
À définir sur l'événement de manière simple:
Événement est un RÉFÉRENCE à un délégué avec deux restrictions
Deux ci-dessus sont les points faibles pour les délégués et il est adressé à l'événement. Exemple de code complet pour montrer la différence dans un violon est ici https://dotnetfiddle.net/5iR3fB .
Basculer le commentaire entre l'Événement et le Délégué et le code client qui invoque/affecter des valeurs à déléguer à comprendre la différence
Voici le code en ligne.
OriginalL'auteur Venkatesh Muniyandi
Covariance
etContravariance
offrir une plus grande souplesse pour le délégué des objets. D'autre part, un événement n'a pas de tels concepts.Covariance
permet d'affecter une méthode pour le délégué, où l'le type de retour de la méthode est une classe dérivée de la classe
qui spécifie le type de retour de la délégation.
Contravariance
permet d'affecter une méthode pour le délégué, oùle type de paramètre de la méthode est une classe de base de la classe qui est
spécifié en tant que paramètre du délégué.
OriginalL'auteur vivek nuna
Délégué est un type sûr de pointeur de fonction. L'événement est une implémentation de l'éditeur-abonné modèle de conception à l'aide de délégué.
OriginalL'auteur Weidong Shen