¿Por qué necesitamos la palabra clave “evento” al definir eventos?

No entiendo por qué necesitamos la palabra clave “evento” mientras definimos los eventos, cuando podemos hacer lo mismo sin utilizar la palabra clave “evento”, simplemente usando los delegates.

p.ej

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

Aquí, si elimino la palabra clave “evento” de la segunda línea, también puedo plantear el evento invocando al delegado. ¿Alguien puede decirme por qué es necesaria esta palabra clave de evento?

Los eventos similares a campos y los campos públicos de tipos de delegates se ven similares, pero en realidad son muy diferentes.

Un evento es fundamentalmente como una propiedad: es un par de métodos para agregar / eliminar (en lugar de obtener / establecer una propiedad). Cuando declara un evento parecido a un campo (es decir, uno en el que no especifica los bits para agregar / eliminar), se crea un evento público y un campo de respaldo privado. Esto le permite plantear el evento de forma privada, pero permitir la suscripción pública. Con un campo de delegado público, cualquiera puede eliminar los controladores de eventos de otras personas, organizar el evento por sí mismos, etc. – es un desastre de encapsulación.

Para más información sobre eventos (y delegates), lea mi artículo sobre este tema . (En algún momento necesito actualizar esto para C # 4, que cambia muy poco los eventos de campo. Sin embargo, su esencia sigue siendo correcta).

La palabra clave de evento hace 3 cosas diferentes:

  1. Puede definir un evento en una interfaz, aunque no pueda definir campos regulares en las interfaces.
  2. Cambia la visibilidad de los operadores = y () (asignación e invocación) a privado, de modo que solo la clase contenedora pueda invocar el evento o anular todos los métodos contenidos en él. Los operadores -= y += todavía se pueden invocar en un evento desde fuera de la clase que lo define (obtienen el modificador de acceso que escribió junto al evento).
  3. También puede anular el modo -= y += comportarse en eventos.

Las otras respuestas están bien; Me gustaría agregar algo más en qué pensar.

Su pregunta es “¿por qué necesitamos eventos cuando tenemos campos de tipo de delegado?” Extendería esa pregunta: ¿por qué necesita métodos, propiedades, eventos, constructores de instancias o finalizadores si tiene campos de tipo delegado? ¿Por qué necesita algo más que campos que contienen valores y delegates en un tipo? Por qué no solo decir

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

?

No necesita métodos, propiedades o eventos. Le damos esas cosas porque los patrones de diseño de métodos, propiedades y eventos son importantes y útiles, y merecemos tener una forma estándar, documentada y clara para implementarlos en el idioma.

En parte es necesario porque si omite la palabra clave del event , rompe la encapsulación. Si solo se trata de un delegado público de multidifusión, cualquiera puede invocarlo, establecerlo como nulo o manipularlo. Si existe una clase llamada MailNotifier y tiene un evento llamado MailReceived , no tiene sentido que otros tipos puedan mailNotifier.MailReceived() ese evento llamando a mailNotifier.MailReceived() ;

Por otro lado, solo puede inmiscuirse e invocar eventos ‘de tipo campo’ del tipo que lo definió.

Si quieres mantener privada la invocación de tu evento, no hay nada que te impida hacer algo como esto:

 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(...); } } 

… pero eso es una gran cantidad de código para (más o menos) hacer lo que los eventos de campo ya nos dan.

Los eventos tienen ventajas distintas en comparación con los campos de delegado. Los eventos se pueden definir en las interfaces en contraste con los campos, agregando abstracción al código, y aún más importante: los eventos solo se pueden llamar desde dentro de la clase de definición. En tu caso, cualquiera podría llamar al evento, posiblemente destruyendo tu código.

Vea esta publicación en el blog para más información.