views:

294

answers:

3

What is the difference between eventOne (with keyword 'event') and eventTwo (w/o keyword)?

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();
    }
}
+9  A: 
  • eventOne is a public event backed by a private field of type EventHandler.
  • eventTwo is a public field of type EventHandler.

Basically an event only encapsulates the ideas of "subscribe" and "unsubscribe" in the same way that a property only encapsulates the ideas of "get" and "set" rather than the actual storage. (As far as the CLR is concerned an event can also expose a "raise" method, but C# never uses this. Ignore it.)

See my article on events for more about the difference between delegates and events.

Jon Skeet
Have you had a look at actual IL? You will be amazed.
Prankster
Yes, I have. What amazed you?
Jon Skeet
While 'add' and 'remove' are actually generated, compiler optimized them out, so in the code above the only difference will be access modifiers on delegates.
Prankster
No, the compiler isn't "optimising them out". *Within* the class, eventOne refers to the field. From *outside* the class, it refers to the event.
Jon Skeet
(See section 10.8.1 of the C# 3.0 spec for more details.)
Jon Skeet
+6  A: 

By using the event keyword you tell C# go generate to hidden methods, add_XXX and remove_XXX for your underlying delegate. This makes sure that anyone using your class can only attach and remove delegates to the event. The key point is that nobody outside your class and raise the event, so you've got complete control over when this will happen.

If you don't use event then you're just exposing a public delegate that anyone can add to, remove from and invoke. It's highly unlikely that you want anyone other than your class to do the invoking.

Sean
So the reason Prankster's code shows no apparent difference is because all the actions on eventOne and eventTwo were performed within the same class? Code that accessed them from a different class would illustrate the difference?
Rob Kennedy
+1  A: 

This is the program for illustrating the difference, taking into account the answers before

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);
    }
}
Jhonny D. Cano -Leftware-