2009-04-02 8 views
15

Quelle est la différence entre eventOne (avec mot-clé 'event') et eventTwo (mot-clé w/o)?Le mot clé 'event' est-il facultatif 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(); 
    } 
} 

Répondre

20
  • eventOne est un événement publique soutenu par un champ privé de type EventHandler.
  • eventTwo est un champ public de type EventHandler.

Fondamentalement, un événement ne encapsule les idées de « subscribe » et « désabonnement » de la même manière qu'une propriété encapsule que les idées de « get » et « set » plutôt que le stockage réel. (En ce qui concerne le CLR, un événement peut également exposer une méthode "raise", mais C# ne l'utilise jamais.)

Voir my article on events (alternate link) pour en savoir plus sur la différence entre les délégués et les événements.

+0

Avez-vous un oeil à l'IL réelle? Vous serez étonné. – Prankster

+0

Oui, j'ai. Qu'est-ce qui vous a étonné? –

+0

Alors que 'ajouter' et 'supprimer' sont réellement générés, le compilateur les a optimisés, donc dans le code ci-dessus la seule différence sera les modificateurs d'accès sur les délégués. – Prankster

16

En utilisant l'événement mot-clé vous dire C# vont générer des méthodes cachées, add_XXX et remove_XXX pour votre délégué sous-jacent. Cela garantit que toute personne utilisant votre classe peut uniquement attacher et supprimer des délégués à l'événement. Le point clé est que personne en dehors de votre classe et de soulever l'événement, de sorte que vous avez un contrôle complet sur quand cela se produira.

Si vous n'utilisez pas événement, vous exposez simplement un délégué public que n'importe qui peut ajouter, supprimer et invoquer. Il est hautement improbable que vous vouliez que quelqu'un d'autre que votre classe fasse l'invocation.

+0

Donc la raison pour laquelle le code de Prankster ne montre aucune différence apparente est que toutes les actions sur eventOne et eventTwo ont été effectuées dans la même classe? Le code qui leur a accédé d'une classe différente illustrerait la différence? –

8

C'est le programme pour illustrer la différence, en tenant compte des réponses avant

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