Wednesday, June 20, 2012

Events - Adding event keyword to a delegate C#

By now I expect we know how to create a delegate and creating an event using the delegate. Let us get into details how adding event keyword changes the way delegate is treated.

An 'event' keyword in front of a delegate does more than exposing the delegate type to Subscribers. Here subscribers refers to classes that add methods to the delegate by  exposed  Broadcaster. Broadcaster is the class that exposes the delegate type with keyword event. 

When compiler discovers event declaration, it does three things that makes event different than a normal delegate. 

void delegate DateTimeHandler(object sender, TimeEventArgs args);
public event DateTimeHandler DataTimeChanged;

1. Compiler creates an event accessor for the just like Property accessor. 

 DateTimeHandler _timeHandler;
public DateTimeHandler DateTimeChanged
{
      add { _timeHandler += value;}
      remove { _timeHandler -= value;}
}

2. Compiler checks for any references to DateTimeChanged inside the Broadcaster class which are other than += and -= operations and redirects them to underlying private _timeHandler delegate field.

3. Compiler translates all the += and -= operations to the event accessor which compiler resolved in step 1. This make behavior + and - different when applied to events.

Differences between a normal delegate and an event in terms of their behaviors are listed below:
      
       1. An event can only be invoked by the broadcaster, in case of delegate it can be invoked by any class that has access to it. In case of delegate a subscriber class can call\broadcast to other subscribers by invoking the delegate.

      2. A normal delegate can be cleared off\ reset by the class that is using it. Any class that has access to delegate can set the delegate to its own method and thereby clear off methods that were assigned by all delegates.

     3. An event can only subscribed to or unsubscribed but the subscribers list or methods associated with event can not be modified or cleared as that can happen with normal delegate.

Consider the case when DateTimeHandler delegate in above example is exposed instead of event DataTimeChaneged. Lets assume class A and Class B use this delegate by giving their own method like below.

Controller.Instance. DateTimeHandler += a.MethodA;
Controller.Instance. DateTimeHandler += b.MethodB;

Some other class C which also can access to event can set DateTimeHandler to  different definition altogether and there by make it loose all other subscribers(i.e. A and B) information and initialization.

Controller.Instance. DateTimeHandler = c.MethodC; //Now controller's delegate loses track of all other subscribers and methods.

Class C can also invoke DateTimeHandler delegate there by calling MethodA and MethodB of  class A and Class B respectively, like below:

if(isBadIntention)
{
      Controller.Instance.DateTimeHandler(this, dummyEventArgs);
}

Reference:
All thanks to "C# 4.0 in Nutshell" by Joe Albahari. I have written here what I have understood from Albahari's book and also from my learning.



No comments:

Post a Comment