2010-06-12 14 views
76

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 delegados.¿Por qué necesitamos la palabra clave "evento" al definir eventos?

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 quito la palabra clave "evento" de la segunda línea, entonces también puedo provocar el evento mediante la invocación del delegado. ¿Alguien puede decirme por qué es necesaria esta palabra clave de evento?

+0

ok si no utiliza la palabra clave de evento cualquiera que pueda acceder a ese evento utilizando el objeto de clase, configúrelo como NULL como objClass.SelectedIndexChanged = null. esto bloqueará tu código subyacente. la palabra clave de evento impone al usuario asignar algo similar a delegar usando + =. –

Respuesta

92

campo-como y campos públicos de tipos de delegado parecen similares, pero en realidad son muy diferentes.

Un evento es fundamentalmente como una propiedad: es un par de métodos de agregar/quitar (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 delegado público, cualquiera puede eliminar los controladores de eventos de otras personas, plantear el evento por sí mismos, etc. - es un desastre de encapsulación.

Para obtener más información sobre eventos (y delegados), lea mi article on this topic. (En algún momento tengo que actualizar esto para C# 4, que cambia muy poco los eventos de campo. Sin embargo, su esencia sigue siendo correcta)

+4

Esto es mil veces mejor que la explicación oficial de una línea de MSDN: 'La palabra clave del evento se utiliza para declarar un evento en una clase de editor.' – cowlinator

5

Es parcialmente necesario porque si omite la palabra clave 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 desencadenar ese evento llamando al mailNotifier.MailReceived();

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

Si quería mantener su invocación evento privado, no hay nada que le 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 carga completa de código sólo para (más o menos) hacen lo eventos de campo ya nos dan.

+0

También sería más difícil para cosas como los diseñadores usar ... básicamente basarías en nombrar convenciones para métodos, en lugar de metadatos públicos que dicen "esto es un evento". –

3

Los eventos tienen distintas ventajas 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.

Consulte this blog post para obtener más información.

+2

No debería estar comparando eventos y * delegados * - compare eventos y * campos públicos con un tipo de delegado *. Y no, el marco * no * requiere que los eventos tengan esa firma. Puede crear un evento de cualquier tipo de delegado que desee. –

+0

Muchas gracias. No estaba claro en los libros. – teenup

+0

gracias jon, fijo. – Femaref

16

La palabra clave evento hace 3 cosas diferentes:

  1. Se puede definir un evento en una interfaz, a pesar de que no se pueden 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 += aún 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 la forma en que -= y += se comportan en eventos. eventos
+0

Verificar http://pastebin.com/TMpib9ux He proporcionado algunos ejemplos. :) –

+0

muy clara su explicación – lucasasecas

16

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 cualquier cosa que no sean campos que contienen valores y delegados en un tipo? ¿Por qué no simplemente decir

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

?

Usted 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.

+1

¡Guau! ¡Recuerda por qué amo C#! De todos los idiomas con los que he trabajado, tiene el equilibrio adecuado de compacidad, flexibilidad y semántica legible. El único lenguaje comparable es Object Pascal. –

+0

Eso no es lo que estaba pidiendo .. Hizo una pregunta razonable, ¿por qué necesitamos la palabra clave del evento, es decir, incluso hace algo ... qué diferencia hace, cuándo sería útil? Y su pregunta lo compara con por qué necesitaríamos métodos y propiedades, entonces, ¿por qué necesitamos objetos, por qué OOP, por qué métodos, por qué procedimientos, por qué no solo programación imperativa ... Y dice "porque es útil". Bueno obviamente. Preguntaba en particular, no por qué los métodos son útiles, ni por qué OOP es útil. Y solo decir que la palabra clave de evento es útil no lo corta sin decir por qué. – barlop

+0

@barlop: Bueno, siéntase libre de escribir la respuesta que prefiera a esta pregunta de siete años si no le gusta esta. De esa forma todo el sitio mejora. –

Cuestiones relacionadas