2009-04-02 16 views
15

¿Cuál es la diferencia entre eventOne (con la palabra clave 'event') y eventTwo (sin la palabra clave)?¿La palabra clave 'evento' es opcional en C#?

class Program 
{ 
    public event EventHandler eventOne; 
    public EventHandler eventTwo; 

    public void RaiseOne() 
    { 
     if (eventOne != null) 
      eventOne(this, EventArgs.Empty); 
    } 

    public void RaiseTwo() 
    { 
     if (eventTwo != null) 
      eventTwo(this, EventArgs.Empty); 
    } 

    static void Main(string[] args) 
    { 
     var p = new Program(); 
     p.eventOne += (s, e) => Console.WriteLine("One"); 
     p.eventTwo += (s, e) => Console.WriteLine("Two"); 
     p.RaiseOne(); 
     p.RaiseTwo(); 
    } 
} 

Respuesta

20
  • eventOnees un evento público respaldado por un campo privado de tipo EventHandler.
  • eventTwo es un campo público del tipo EventHandler.

Básicamente un evento solamente encapsula las ideas de "suscribirse" y "baja" de la misma manera que una propiedad única encapsula las ideas de "get" y "set" en lugar del almacenamiento real. (En lo que se refiere al CLR un evento también puede exponer a un método de "aumento", pero C# nunca usa esto. Ignorarlo.)

Ver my article on events (alternate link) para más información sobre la diferencia entre los delegados y eventos.

+0

¿Ha tenido un vistazo a IL real? Te sorprenderás. – Prankster

+0

Sí, tengo. ¿Qué te sorprendió? –

+0

Si bien 'add' y 'remove' se generan en realidad, el compilador los optimizó, por lo que en el código anterior la única diferencia serán los modificadores de acceso en los delegados. – Prankster

16

Al utilizar el evento palabra clave que dicen C# vaya a generar métodos ocultos, add_XXX y remove_XXX para su delegado subyacente. Esto asegura que cualquier persona que use su clase solo pueda adjuntar y eliminar delegados al evento. El punto clave es que nadie fuera de tu clase y plantee el evento, por lo que tienes un control total sobre cuándo sucederá.

Si no usa evento, entonces solo está exponiendo a un delegado público al que cualquiera puede agregar, eliminar e invocar. Es muy poco probable que desee que alguien que no sea su clase haga la invocación.

+0

¿Por qué el código de Prankster no muestra una diferencia aparente porque todas las acciones en eventOne y eventTwo se realizaron dentro de la misma clase? ¿El código que accede a ellos desde una clase diferente ilustraría la diferencia? –

8

Este es el programa para ilustrar la diferencia, teniendo en cuenta las respuestas antes de

using System; 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var a = new A(); 
     a.eventOne += (s, e) => Console.WriteLine("One"); 
     a.eventTwo += (s, e) => Console.WriteLine("Two"); 
     a.RaiseOne(); 
     a.RaiseTwo(); 
       // won't compile 
     a.eventOne(null, EventArgs.Empty); 
     a.eventTwo(null, EventArgs.Empty); 
    } 

} 

class A { 
    public event EventHandler eventOne; 
    public EventHandler eventTwo; 

    public void RaiseOne() 
    { 
     if (eventOne != null) 
      eventOne(this, EventArgs.Empty); 
    } 

    public void RaiseTwo() 
    { 
     if (eventTwo != null) 
      eventTwo(this, EventArgs.Empty); 
    } 
} 
Cuestiones relacionadas