110 votes

Différence entre les événements et les délégués et leurs applications respectives

Je ne vois pas l'avantage d'utiliser les événements plutôt que les délégués, si ce n'est le sucre syntaxique. Peut-être que je ne comprends pas bien, mais il semble que l'événement soit juste un substitut du délégué.

Pouvez-vous m'expliquer les différences et quand utiliser l'un ou l'autre ? 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 les délégués plutôt que les événements et vice versa ? Veuillez indiquer votre expérience réelle avec les deux, par exemple dans le code de production.

55voto

Peter Wone Points 7672

Le mot-clé event est un modificateur de portée pour les délégués multidiffusion. Les différences pratiques entre cette méthode et la simple déclaration d'un délégué multidiffusion sont les suivantes :

  • Vous pouvez utiliser event dans une interface.
  • L'accès aux invocations du délégué multidiffusion est limité à la classe déclarante. Le comportement est le même que si le délégué était privé pour l'invocation. Pour les besoins de l'affectation, l'accès est tel que spécifié par un modificateur d'accès explicite (ex. public event ).

A titre d'information, vous pouvez postuler + y - aux délégués de la multidiffusion, et c'est la base de la += y -= pour l'affectation combinée de délégués à des événements. Ces trois extraits sont équivalents :

B = new EventHandler(this.MethodB);
C = new EventHandler(this.MethodC);
A = B + C;

Deuxième exemple, illustrant l'affectation directe et l'affectation combinée.

B = new EventHandler(this.MethodB);
C = new EventHandler(this.MethodC);
A = B;
A += C;

Troisième exemple : une syntaxe plus familière. Vous êtes probablement familier avec l'affectation de null pour supprimer tous les gestionnaires.

B = new EventHandler(this.MethodB);
C = new EventHandler(this.MethodC);
A = null;
A += B;
A += C;

Comme les propriétés, les événements ont une syntaxe complète que personne n'utilise jamais. Ceci :

class myExample 
{
  internal EventHandler eh;

  public event EventHandler OnSubmit 
  { 
    add 
    {
      eh = Delegate.Combine(eh, value) as EventHandler;
    }
    remove
    {
      eh = Delegate.Remove(eh, value) as EventHandler;
    }
  }

  ...
}

...fait exactement la même chose que ça :

class myExample 
{
  public event EventHandler OnSubmit;
}

Les méthodes add et remove sont plus visibles dans la syntaxe plutôt guindée qu'utilise VB.NET (pas de surcharges d'opérateurs).

49voto

Szymon Rozga Points 11277

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 possède une propriété appelée Limit, et elle déclenche un événement lorsque le cours de l'action atteint la Limit. Cette notification est effectuée via un événement. Le fait que quelqu'un se soucie réellement de cet événement et y souscrive ne concerne pas la classe propriétaire.

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 de multidiffusion. 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 parfait d'implémenter la fonction Modèle de stratégie . Par exemple, si je veux trier une liste d'objets, je peux fournir une stratégie Comparator à la méthode pour indiquer à l'implémentation comment comparer deux objets.

J'ai utilisé les deux méthodes dans un code de production. Des tonnes de mes objets de données notifient lorsque certaines propriétés sont satisfaites. L'exemple le plus simple est le suivant : lorsqu'une propriété est modifiée, un événement PropertyChanged est déclenché (voir l'interface INotifyPropertyChanged). J'ai utilisé des délégués dans le code pour fournir différentes stratégies pour transformer 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.

30voto

Jonathon Watney Points 2318

J'ai trouvé cette page très utile pour comprendre la différence.

http://blog.monstuff.com/archives/000040.html

12voto

Sean Points 905

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 et d'interfaces (plus de sucre) donne l'eau à la bouche. Les délégués et les classes abstraites virtuelles pures sont beaucoup moins appétissants.

5voto

itowlson Points 44174

Les événements sont marqués comme tels dans les métadonnées. Cela permet aux concepteurs de Windows Forms ou d'ASP.NET, par exemple, de distinguer les événements des simples propriétés de type délégué, et de leur fournir un support approprié (en les affichant notamment 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 :

someObj.SomeCallback = MyCallback;  // okay, replaces any existing callback
someObj.SomeEvent = MyHandler;  // not okay, must use += instead

Cela permet d'isoler les abonnés aux événements : Je peux ajouter mon gestionnaire à un événement, et vous pouvez ajouter votre gestionnaire au même événement, et vous ne risquez pas d'écraser accidentellement mon gestionnaire.

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