Pour comprendre les différences, vous pouvez examiner ces deux exemples.
Exemple avec les délégués (dans ce cas, l'action est un type de délégué qui ne renvoie pas de valeur).
public class Animal
{
public Action Run {get; set;}
public void RaiseEvent()
{
if (Run != null)
{
Run();
}
}
}
pour utiliser le délégué vous devez 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 ceci
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, j'ai remplacé les comportements précédents, mais il manque juste un élément +
(J'ai utilisé +
au lieu de +=
)
Un autre point faible est que chaque classe qui utilise votre Animal
peut soulever RaiseEvent
Je l'appelle juste animal.RaiseEvent()
.
Pour éviter ces points faibles, vous pouvez utiliser events
en c#.
Votre classe d'animaux changera de la manière suivante
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 appeler des événements
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'utilisez pas une propriété publique mais un champ public (avec les événements, le compilateur protège vos champs d'un accès non désiré)
- Les événements ne peuvent pas être affectés directement. Dans ce cas, vous ne pouvez pas faire l'erreur précédente que j'ai montrée en surchargeant le comportement.
- Personne en dehors de votre classe ne peut relancer l'événement.
- Les événements peuvent être inclus dans une déclaration d'interface, alors qu'un champ ne le peut pas.
notes
EventHandler est déclaré comme le délégué suivant :
public delegate void EventHandler (object sender, EventArgs e)
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 EventHAndler
au lieu de cet exemple qui utilise EventHandler<ArgsSpecial>
se référer à aquí pour la documentation sur les EventHandler