tags:

views:

375

answers:

5

I don't understand why do we need the "event" keyword while defining events, when we can do the same thing without using "event" keyword, just by using the delegates.

e.g.

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

Here if I remove the "event" keyword from the second line, then also I can raise the event by invoking the delegate. Can anybody please tell me why is this event keyword needed ?

+1  A: 

It's partly needed because if you omit the event keyword, it breaks encapsulation. If it's just a public multicast delegate, anyone can invoke it, set it to null or tamper with it. If a class called MailNotifier exists and it has an event called MailReceived, it makes no sense for other types to be able to fire that event via calling mailNotifier.MailReceived();

On the other hand, you can only meddle with and invoke 'field like' events from the type that defined it.

If you wanted to keep your event invocation private, there's nothing to stop you doing something like this:

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

... but that's a whole load of code just to (more or less) do what field-like events already give us.

Mark Simpson
@Mark: It would also be harder for things like designers to use... you'd basically be relying on naming conventions for methods, instead of there being public metadata saying "this is an event".
Jon Skeet
+2  A: 

Events have distinct advantages compared to delegate-fields. Events can be defined in interfaces in contrast to fields, adding abstraction to the code, and even more importantly: Events can only be called from inside the defining class. In your case, anybody could call the event, possibly destroying your code.

See this blog post for further information.

Femaref
You shouldn't really be comparing events and *delegates* - compare events and *public fields with a delegate type*. And no, the framework *doesn't* require events to have that signature. You can create an event of any delegate type you like.
Jon Skeet
Thanks a lot. It was not clear from the books.
Puneet Dudeja
thanks jon, fixed.
Femaref
A: 

The event keyword does 3 different things:

  1. You can define an event in an interface, even though you cannot define regular fields in interfaces.
  2. It changes the visibility of the = and () operators (assignment and invocation) to private, so that only the containing class can invoke the event or override all the methods contained in it. The -= and += operators can still be invoked on an event from outside the class defining it (they get the access modifier you wrote next to the event).
  3. You can also override the way -= and += behave on events.
Oak
+13  A: 

Field-like events and public fields of delegate types look similar, but are actually very different.

An event is fundamentally like a property - it's a pair of add/remove methods (instead of the get/set of a property). When you declare a field-like event (i.e. one where you don't specify the add/remove bits yourself) a public event is created, and a private backing field. This lets you raise the event privately, but allow public subscription. With a public delegate field, anyone can remove other people's event handlers, raise the event themselves, etc - it's an encapsulation disaster.

For more on events (and delegates) read my article on this topic. (At some point I need to update this for C# 4, which changes field-like events very slightly. The gist of it is still correct though.)

Jon Skeet
Thanks Jon, your article is really good!!
Puneet Dudeja
+2  A: 

The other answers are fine; I'd just like to add something else to think about.

Your question is "why do we need events when we have fields of delegate type?" I would extend that question: why do you need methods, properties, events, instance constructors or finalizers if you have fields of delegate type? Why do you need anything other than fields that contain values and delegates in a type? Why not just say

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

?

You don't need methods, properties or events. We give you that stuff because the method, property and event design patterns are important and useful, and deserve to have a standard, documented, clear way to implement them in the language.

Eric Lippert