Quelles sont les différences entre les délégués et les événements? Ne pas tous les deux contenir des références à des fonctions qui peuvent être exécutées?
Réponses
Trop de publicités?pour comprendre les différences, vous pouvez regarder cette 2 exemples
Exemple avec les Délégués (Action, dans ce cas, c'est une sorte de délégué qui ne débite pas de valeur de retour)
public class Animal
{
public Action Run {get; set;}
public void RaiseEvent()
{
if (Run != null)
{
Run();
}
}
}
pour utiliser le délégué, vous devriez faire quelque chose comme ceci
Animale animal= new Animal();
animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running") ;
animal.RaiseEvent();
ce code fonctionne bien, mais vous pourriez avoir quelques points faibles.
Par exemple si j'écris ce
animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running");
animal.Run = () => Console.WriteLine("I'm sleeping") ;
avec la dernière ligne de code que j'ai dû remplacer les comportements précédents, avec juste un manque +
(j'ai utilisé l' +
au lieu de +=
)
Un autre point faible est que chaque classe qui utilisent votre Animal
classe peut soulever RaiseEvent
seulement en l'appelant animal.RaiseEvent()
.
Pour éviter cela, des points faibles, vous pouvez utiliser events
en c#.
Votre Animal de la classe va changer de cette façon
public class ArgsSpecial :EventArgs
{
public ArgsSpecial (string val)
{
Operation=val;
}
public string Operation {get; set;}
}
public class Animal
{
public event EventHandler<ArgsSpecial> Run = delegate{} //empty delegate. In this way you are sure that value is always != null because no one outside of the class can change it
public void RaiseEvent()
{
Run(this, new ArgsSpecial("Run faster"));
}
}
pour les événements d'appels
Animale animal= new Animal();
animal.Run += (sender, e) => Console.WriteLine("I'm running. My value is {0}", e.Operation );
animal.RaiseEvent();
Différences:
- Vous n'êtes pas à l'aide d'une propriété publique, mais un champ public (avec des événements le compilateur protéger les champs contre les accès non autorisés)
- Événements ne peuvent pas être directement affectés. Dans ce cas, vous ne pouvez pas faire l'erreur précédente que je vous l'ai montré substituer le comportement.
- Personne en dehors de votre classe peut déclencher l'événement.
- Les événements peuvent être inclus dans une déclaration d'interface, alors qu'un champ ne peut pas
notes
Ce gestionnaire est déclaré en tant que délégué suivant:
public delegate void EventHandler (object sender, EventArgs e)
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.
Vous pouvez aussi utiliser l' EventHAndler
au lieu cet exemple que l'utilisation EventHandler<ArgsSpecial>
reportez-vous ici pour la documentation sur EventHandler
En plus de la syntaxe et de propriétés fonctionnelles, il y a aussi un semantical différence.
Les 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é.
Les é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 s'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).
C'est un vieux post, mais si quelqu'un trébuche sur elle, comme je l'ai fait ici est un autre 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 -
"Supposons que les événements n'existent pas en tant que concept en C#/.NET. Comment une autre classe de s'abonner à un événement?
Trois options:
public delegatevariable
délégué variable soutenu par une propriété
délégué variable avec AddXXXHandler et RemoveXXXHandler méthodes
L'Option 1 est clairement horrible, pour toutes les raisons que nous avons en horreur les variables publiques.
L'Option 2 est mieux, mais permet aux abonnés de remplacer efficacement uns les autres, il serait trop facile d'écrire someInstance.MyEvent = gestionnaire d'événements, et qui remplacent toutes les gestionnaires d'événements plutôt que l'ajout d'un nouveau. En outre, vous devez toujours écrire l' les propriétés.
L'Option 3 est essentiellement ce que les événements de vous donner, mais avec une garantie de convention (généré par le compilateur et soutenu par des indicateurs dans le IL) et "libre" de la mise en œuvre si vous êtes heureux avec la sémantique le domaine-comme les événements de vous donner. S'abonner ou se désabonner à événements est encapsulé sans laisser l'arbitraire l'accès à la liste de gestionnaires d'événements, et les langues peuvent rendre les choses plus simples en fournissant syntaxe tant en terme de déclaration et d'abonnement."