Pourquoi avons-nous besoin du mot-clé «event» lors de la définition des événements?

Je ne comprends pas pourquoi avons-nous besoin du mot-clé “event” lors de la définition des événements, alors que nous pouvons faire la même chose sans utiliser le mot-clé “event”, simplement en utilisant les delegates.

par exemple

public delegate void CustomEventHandler(int a, ssortingng 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 appelant le délégué. Quelqu’un peut-il s’il vous plaît me dire pourquoi ce mot-clé d’événement est nécessaire?

Les événements de type champ et les champs publics des types delegates ont une apparence similaire, mais sont en réalité très différents.

Un événement est fondamentalement comme une propriété – c’est une paire de méthodes add / remove (au lieu de get / set d’une propriété). Lorsque vous déclarez un événement de type champ (c.-à-d. Un événement où vous ne spécifiez pas les bits d’ajout / suppression vous-même), un événement public est créé et un champ de sauvegarde privé. Cela vous permet de déclencher l’événement en privé, mais d’autoriser l’abonnement public. Avec un champ de délégué public, n’importe qui peut supprimer des gestionnaires d’événements d’autres personnes, déclencher l’événement eux-mêmes, etc. – c’est un désastre d’encapsulation.

Pour plus d’informations sur les événements (et les delegates), lisez mon article sur ce sujet . (À un moment donné, je dois le mettre à jour pour C # 4, ce qui modifie très légèrement les événements de type champ. L’essentiel est néanmoins correct.)

Le mot-clé event fait trois 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 réguliers dans les interfaces.
  2. Il modifie la visibilité des opérateurs = et () (assignation et invocation) en private, de sorte que seule la classe contenant peut invoquer l’événement ou remplacer toutes les méthodes qu’il contient. Les opérateurs -= et += peuvent toujours être appelés sur un événement extérieur à la classe le définissant (ils obtiennent le modificateur d’access que vous avez écrit à côté de l’événement).
  3. Vous pouvez également remplacer le mode -= et += se comporter sur les événements.

Les autres réponses sont bonnes; Je voudrais juste append quelque chose à penser.

Votre question est “pourquoi avons-nous besoin d’événements lorsque nous avons des champs de type délégué?” Je voudrais étendre cette question: pourquoi avez-vous besoin de méthodes, propriétés, événements, constructeurs d’instance ou finaliseurs si vous avez des champs de type délégué? Pourquoi avez-vous besoin d’ autre chose que des champs contenant des valeurs et des delegates dans un type? Pourquoi ne pas simplement dire

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

?

Vous n’avez pas besoin de méthodes, de propriétés ou d’événements. Nous vous donnons ce genre de choses, car les modèles de conception des méthodes, des propriétés et des événements sont importants et utiles et méritent d’avoir une méthode standard, documentée et claire pour les implémenter dans le langage.

Cela est en partie nécessaire car si vous omettez le mot-clé event , il casse l’encapsulation. S’il ne s’agit que d’un délégué public multidiffusion, n’importe qui peut l’invoquer, le définir sur null ou le modifier. Si une classe appelée MailNotifier existe et qu’il a un événement appelé MailReceived , cela n’a aucun sens que d’autres types puissent déclencher cet événement en appelant mailNotifier.MailReceived() ;

D’autre part, vous ne pouvez manipuler et invoquer des événements de type “champ comme” que dans le type qui l’a défini.

Si vous souhaitez garder votre appel privé à l’appel, rien ne vous empêche de faire quelque chose comme ceci:

 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 une charge de code juste pour (plus ou moins) faire ce que les événements de type terrain nous donnent déjà.

Les événements ont des avantages distincts par rapport aux champs delegates. Les événements peuvent être définis dans des interfaces contrairement aux champs, en ajoutant une abstraction au code, et plus important encore: les événements ne peuvent être appelés qu’à partir de la classe de définition. Dans votre cas, n’importe qui peut appeler l’événement, détruisant éventuellement votre code.

Voir ce blog pour plus d’informations.