13.6.12

Difference Between Events And Delegates in C#



It might be the syntax of C# that provides us with shortcuts to write delegates and events that causes this confusion.

In short, a delegate is a class that contains a field that holds a reference to a method and then you can call the method with appropriate parameters. Whereas an event is a variable that you can define and specify one or more delegates to be added to it.

Let's go through these examples to simplify and illustrate the idea.

class Program
{
  static void Main(string[] args)
  {
    DelegatesAndEvents obj = new DelegatesAndEvents();
    obj.Execute();
  }
}


public class DelegatesAndEvents
{
  public delegate void MyDelegate(int val);

  internal void Execute()
  {

    MyDelegate d = new
    MyDelegate(this.MyMethod);

    int val = 15;

    d.Invoke(val);
  }

  void MyMethod(int val)
  {
    Console.WriteLine(val);
    Console.ReadLine();
  }
}


In the previous code, I create a delegate type and name it MyDelegate. This delegate type is designed to call methods that take one parameter of type integer. What actually happens behind the scenes is that the CLR creates a class called MyDelegate and this class would have some fields and a method called Invoke. The invoke method takes one parameter of type integer.

In the execute method, I create an instance of the delegate (recall that a delegate is a class and I can create instances from it like any other class). The constructor of this MyDelegate takes one parameter of type integer. However, what I actually pass to the constructor is the name of the method I want to invoke and it will implicitly understand that I'm passing a reference to the method.

Another point that is worth mentioning is that I could have invoked the method without using the Invoke method. This is just a syntactical shortcut provided by C#. It would be like this:
d(val);


Now let's change our code a little bit. (comment added to show added, removed and changed code)
public class DelegatesAndEvents
{

  public delegate void MyDelegate(object sender, EventArgs e); // Changed

  internal void Execute()
  {

    MyDelegate d = new
    MyDelegate(this.MyMethod);

    EventArgs e = new EventArgs(); // Added
    object sender = 15; // Added

    d(sender, e); // Changed
  }

  void MyMethod(object sender, EventArgs e)
  {
    Console.WriteLine(sender);
    Console.ReadLine();
  }
}


What I did is just changing the parameters that MyDelegate is designed to take. Instead of taking one parameter of type integer, it now takes 2 parameters of types object and EventArgs, respectively. There's no big deal so far.

Now I will introduce an event and see how to use it. I will change the code a little bit. (comment added to show added, removed and changed code )

public class DelegatesAndEvents
{

  public delegate void MyDelegate(object sender, EventArgs e);
  public event MyDelegate MyEvent; // Added

  internal void Execute()
  {

    MyDelegate d = new MyDelegate(this.MyMethod);

    object sender = 15;
    EventArgs e = new EventArgs();

    MyEvent += new MyDelegate(d); // Added

    MyEvent(sender, e); // Added

    //d(sender, e);  Removed
  }


  void MyMethod(object sender, EventArgs e)
  {
    Console.WriteLine(sender);
    Console.ReadLine();
  }
}


Here's what I did in the last code change.I declared an event of type MyDelegate. In other words, I created an event that can hold delegates of type MyDelegate, so in the future I can use this event to invoke methods with the signature MyDelegate defines (methods that take 2 parameters of type object and EventArgs). And then,instead of invoking MyMethod directly using the delegate, I use the newly created event MyEvent to invoke the method.

As you can see, MyEvent is just a holder of delegates. I can add delegates to this event by using += syntax and passing the delegate instance in the constructor. I can add more than one delegate instance to this event. Look at the following code. (comment added to show added, removed and changed code )

public class DelegatesAndEvents
{

  public delegate void MyDelegate(object sender, EventArgs e);
  public event MyDelegate MyEvent;

  internal void Execute()
  {

    MyDelegate d = new MyDelegate(this.MyMethod);

    object sender = 15;
    EventArgs e = new EventArgs();

    MyDelegate d2 = new MyDelegate(this.MyMethod2); // Added

    MyEvent += new MyDelegate(d);
    MyEvent += new MyDelegate(d2); // Added

    MyEvent(sender, e);
  }

  void MyMethod(object sender, EventArgs e)
  {
    Console.WriteLine(sender);
    Console.ReadLine();
  }

  // This method is added
  void MyMethod2(object sender, EventArgs e)
  {
    Console.WriteLine(sender);
    Console.ReadLine();
  }
}

Instead of adding a delegate instance to the event the normal way, There's a syntax shortcut provided by C# that looks like this:
MyEvent += MyMethod;


So I can change my code to look like this: (comment added to show added, removed and changed code )

class DelegatesAndEvents
{

  public delegate void MyDelegate(object sender, EventArgs e);
  public event MyDelegate MyEvent;

  internal void Execute()
  {      

    //MyDelegate d = new MyDelegate(this.MyMethod);  Removed

    object sender = 15;
    EventArgs e = new EventArgs();

    //MyDelegate d2 = new MyDelegate(this.MyMethod2);  Removed

    MyEvent += MyMethod; // Changed
    MyEvent += MyMethod2; // Changed

    MyEvent(sender, e);
  }

  void MyMethod(object sender, EventArgs e)
  {
    Console.WriteLine(sender);
    Console.ReadLine();
  }


  void MyMethod2(object sender, EventArgs e)
  {
    Console.WriteLine(sender);
    Console.ReadLine();
  }
}


Notice that I no longer need to create delegate instances because the new syntax will implicitly create it.

Finally, let me introduce EventHandler, which is a delegate type itself. You can type EventHandler in your code in Visual Studio and press F12 to discover this.

namespace System
{

  [Serializable]
  [ComVisible(true)]
  public delegate void EventHandler(object sender, EventArgs e);

}


As you can see, EventHandler is a delegate type designed to invoke methods that take 2 parameters, object and EventArgs, exactly like MyDelegate that I defined in the previous code. Therefore, I can replace MyDelegate with EventHandlerand everything will be the same. The final code will be like this:

class DelegatesAndEvents
{    

  //public delegate void MyDelegate(object sender, EventArgs e);  Removed
  public event EventHandler MyEvent; // Changed

  internal void Execute()
  {
    object sender = 15;
    EventArgs e = new EventArgs();

    MyEvent += MyMethod;
    MyEvent += MyMethod;

    MyEvent(sender, e);
  }


  void MyMethod(object sender, EventArgs e)
  {
    Console.WriteLine(sender);
    Console.ReadLine();
  }


  void MyMethod2(object sender, EventArgs e)
  {
    Console.WriteLine(sender);
    Console.ReadLine();
  }
}


Normally, you don't go through all of the previous steps. You only see the last portion of code. All I was trying to do is to show you how this last code came.

now I hope it became clear that delegates are just types that you can create instances from. All delegates inherit from the classMulticastDelegate which is used to invoke other methods according to what we define. Events are meant to hold one or more delegate instance and once you raise the event, it invokes all the methods attached with those delegate instance.




20 comments:

IAbdlkrm said...

http://msdn.microsoft.com/en-us/library/17sde2xt.aspx

Mohammad Abu-Ali said...

Thanks Ibrahim for sharing this article. I'm trying to explain it my way. Hope you found it helpful.

Sanyam Jain said...

Got it...
thanks for such a good explanation

Dumindra said...

Maximum.. superb..

Mohammad Abu-Ali said...

Thanks Sanyam and Dumindra for your comments.

Niyas Mohaideen said...

Good article keep writing more article

Jitendra Kumar said...

Very Good Explaination. Thankyou!

Mohammad Abu-Ali said...

Thanks Niyas and Jitendra. You're welcome

Euphemistic said...

Vvery helpful, indeed!

But please change
MyDelegated = new
MyDelegate(this.MyMethod);
to
MyDelegate d = new
MyDelegate(this.MyMethod);
(more than once)


I've lost a few minutes trying to figure it out!

Mohammad Abu-Ali said...

Thanks for your point Euphemistic. It is corrected now.

Anonymous said...

Great Explanation !!!

Ken Charles said...

Best explanation I could find so far - Well done!

Mohammad Abu-Ali said...

Thanks Ken

Anonymous said...

Your Explanation was superb..Keep it up

Abuzer Asif said...

Thanks for explaining that well... its really awesome...

Mohammad Abu-Ali said...

You're welcome Abuzer

Umanath said...

Neat explains

Sarulatha Arunkumar said...

very very simple and crisp explanation. Thanks

Amir Shaharyar Siddiqui said...

I totally understood the explanation, and it was very clear. but the question is that if both Delegates and events are used for the same purpose, that is, calling methods of similar signatures, then why these are 2 different things? why not only delegates, or only events? after all they both do the exactly same job. Please explain what is the difference. Thanks in advance.

Anonymous said...

Amir Shaharyar Siddiqui, "the event keyword is a modifier for a delegate declaration that allows it to be included in an interface, constraints it invocation from within the class that declares it, provides it with a pair of customizable accessors (add and remove) and forces the signature of the delegate (when used within the .NET framework".
You can take a look here: http://blog.monstuff.com/archives/000040.html

Post a Comment

Popular Posts