143 votes

Pourquoi avons-nous besoin du mot clé "event" pour définir les événements ?

Je ne comprends pas pourquoi nous avons besoin du mot clé "event" pour définir les événements, alors que nous pouvons faire la même chose sans utiliser le mot clé "event", simplement en utilisant les délégués.

par exemple

public delegate void CustomEventHandler(int a, string b);
public event CustomEventHandler customEvent;
customEvent += new CustomEventHandler(customEventHandler);
customEvent(1,"a"); // Raising the event

Ici, si je supprime le mot-clé "event" de la deuxième ligne, je peux également déclencher l'événement en invoquant le délégué. Quelqu'un peut-il me dire pourquoi ce mot clé "event" est nécessaire ?

1 votes

Ok, si vous n'utilisez pas le mot-clé event, toute personne qui peut accéder à cet événement en utilisant l'objet de la classe le met à NULL comme objClass.SelectedIndexChanged = null. cela fera planter votre code sous-jacent. le mot-clé event oblige l'utilisateur à assigner quelque chose de similaire au délégué en utilisant +=.

178voto

Jon Skeet Points 692016

Événements de type champ et champs publics des types de délégués regardez similaires, mais sont en fait très différents.

Un événement est fondamentalement comme une propriété - c'est une paire de méthodes d'ajout/suppression (au lieu des méthodes get/set d'une propriété). Lorsque vous déclarez un événement de type champ (c'est-à-dire un événement pour lequel vous ne spécifiez pas vous-même les bits d'ajout/suppression), un événement public est créé, ainsi qu'un champ de soutien privé. Cela vous permet de déclencher l'événement de manière privée, tout en autorisant l'abonnement public. Avec un champ délégué public, quelqu'un peut supprimer les gestionnaires d'événements d'autres personnes, déclencher l'événement lui-même, etc C'est un désastre d'encapsulation.

Pour plus d'informations sur les événements (et les délégués), lisez mon article intitulé article sur ce sujet . (À un moment donné, je devrai mettre à jour ce document pour C# 4, qui modifie très légèrement les événements de type champ. L'essentiel est cependant toujours correct).

32 votes

C'est mille fois mieux que l'explication officielle en une ligne de MSDN : "Le mot-clé event est utilisé pour déclarer un événement dans une classe d'éditeur".

14 votes

@cowlinator "Hmmm... oui. Le sol ici est fait de sol."

56voto

Oak Points 10667

Le mot-clé d'événement fait 3 choses différentes :

  1. Vous pouvez définir un événement dans une interface, même si vous ne pouvez pas définir de champs ordinaires dans les interfaces.
  2. Il modifie la visibilité de la = y () (affectation et invocation) en privé, de sorte que seule la classe qui le contient peut invoquer l'événement ou remplacer toutes les méthodes qu'il contient. Le site -= y += Les opérateurs peuvent toujours être invoqués sur un événement depuis l'extérieur de la classe qui le définit (ils obtiennent le modificateur d'accès que vous avez écrit à côté de l'événement).
  3. Vous pouvez également modifier la façon dont -= y += se comporter sur les événements.

3 votes

Vous > MSDN. Merci.

31voto

Eric Lippert Points 300275

Les autres réponses sont bonnes ; je voudrais juste ajouter quelque chose d'autre pour y réfléchir.

Votre question est "pourquoi avons-nous besoin d'événements lorsque nous avons des champs de type délégué ?". J'élargirais cette question : pourquoi avez-vous besoin de méthodes, de propriétés, d'événements, de constructeurs d'instance ou de finaliseurs si vous avez des champs de type délégué ? Pourquoi avez-vous besoin de tout ce qui est autres que les champs qui contiennent des valeurs et les délégués dans un type ? Pourquoi ne pas simplement dire

class C
{
    private int z;
    public readonly Func<int, int> M = (int x)=>{ return x+z; }
    // ... and so on
}

?

Tu ne le fais pas. besoin de des méthodes, des propriétés ou des événements. Nous vous donnons ces éléments parce que les modèles de conception de méthodes, de propriétés et d'événements sont importants et utiles, et méritent de disposer d'un moyen standard, documenté et clair de les mettre en œuvre dans le langage.

7 votes

Wow ! Cela rappelle pourquoi j'aime le c# ! De tous les langages avec lesquels j'ai travaillé, il présente le bon équilibre entre compacité, flexibilité et sémantique lisible. Le seul langage comparable est Object Pascal.

5 votes

@ATL_DEV : Il y a une raison à cela. L'architecte du langage C#, Anders Hejlsberg, était auparavant l'architecte de Delphi, qui était un langage basé sur le Pascal objet.

12voto

Mark Simpson Points 10789

C'est en partie nécessaire parce que si vous omettez le event le mot-clé, cela rompt l'encapsulation. S'il s'agit simplement d'un délégué multicast public, n'importe qui peut l'invoquer, le mettre à zéro ou l'altérer. Si une classe appelée MailNotifier existe et il a un événement appelé MailReceived il n'y a aucun sens à ce que d'autres types puissent déclencher cet événement en appelant mailNotifier.MailReceived() ;

D'autre part, vous ne pouvez intervenir et invoquer des événements de type "champ" qu'à partir du type qui l'a défini.

Si vous souhaitez que l'invocation de votre événement reste privée, rien ne vous empêche de faire quelque chose comme ça :

public class MyClassWithNonFieldLikeEvent
{
   private CustomEventHandler m_delegate;

   public void Subscribe(CustomEventHandler handler) 
   {
      m_delegate += handler;        
   }

   public void Unsubscribe(CustomEventHandler handler)
   {          
      m_delegate -= handler;
   }

   private void DoSomethingThatRaisesEvent()
   {
      m_delegate.Invoke(...);
   }       
}

... mais c'est toute une charge de code juste pour faire (plus ou moins) ce que les événements de type champ nous donnent déjà.

0 votes

Il serait également plus difficile à utiliser pour des choses comme les concepteurs... vous dépendriez essentiellement des conventions de nommage pour les méthodes, au lieu qu'il y ait des métadonnées publiques disant "ceci est un événement".

3voto

Femaref Points 41959

Les événements présentent des avantages distincts par rapport aux champs de délégués. Les événements peuvent être définis dans des interfaces, contrairement aux champs, ce qui ajoute de l'abstraction au code, et plus important encore : Les événements ne peuvent être appelés que depuis la classe qui les définit. Dans votre cas, n'importe qui pourrait appeler l'événement, ce qui pourrait détruire votre code.

Voir cet article de blog pour de plus amples informations.

2 votes

Vous ne devriez pas vraiment comparer des événements et délégués - comparer les événements et champs publics avec un type de délégué . Et non, le cadre n'a pas exigent que les événements aient cette signature. Vous pouvez créer un événement de tout type de délégué que vous souhaitez.

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