Delegates in C#

Posted: November 29, 2008 in .NET
Tags: ,

Most of us quite familiar with the delegate keyword in C#.Delegates provides us with a mechanism to encapsulate a method or multiple methods.These are quite like managed version of function pointers in C#.We normally use delegates to define callback methods.

First we need to define a delegate as a type with it’s signature as shown below.Note here the signature includes both parameters as well as return values.

public delegate void DemoDelegate(int i);

To use the delegate we need define a variable to type DemoDelegate ,instantiate the variable by passing a method name of matching signature and then invoke the delegate by passing suitable parameter values as shown in the snippet below:

class DelegateSample
   {
       public void ShowDemo()
       {
 
          DemoDelegate d = new DemoDelegate(Test); //Create instance
           d(10); //Invoke delegate
       }
       public void Test(int i)
       {
           Console.WriteLine(“Method Test called with parameter ” + i);
       }
   }

Now if we take close look into the syntactic details we see all the operation related to delegate closely resembles that of a reference type.So what’s going on inside.On taking a look into the IL code of the assembly we found a new class is generated as shown below:

.class /*02000003*/ public auto ansi sealed DelegateDemo.DemoDelegate
       extends [mscorlib/*23000001*/]System.MulticastDelegate/*01000002*/
{

……….
} // end of class DelegateDemo.DemoDelegate

So the C# compiler internally generates a class with the same name as the delegate type and it inherits from a class System.MulticastDelegate.The class System.MulticastDelegate is derived from base class System.Delegate.This method provides two public attributes

  1. Method – Metadata Method which is getting executed as an instance of System.Reflection.MethodInfo
  2. Target – Stores the instance on which delegate method executes.

Before we proceed further let us take a quick look into another feature of delegate chaining.Refer to the sample below and refer to the lines marked in red.

class DelegateSample
  {
      public void ShowDemo()
      {
          DemoDelegate d1 = new DemoDelegate(Test);
          DemoDelegate d2 = new DemoDelegate(Demo);
          Console.WriteLine(“Delegate Added”);
          DemoDelegate d3 = d1 + d2; //Two delegates are combined
          d3(10); //First method  Test and then Demo is invoked
          Console.WriteLine(“Delegate Removed”);
          DemoDelegate d4 = d3 – d1; //One delegate is removed from the combination
          d4(10);  //Only method Demo is invoked as delegate d1 is removed.
      }
      public void Demo(int i)
      {
          Console.WriteLine(“Method Demo called with parameter ” + i);
      }
      public void Test(int i)
      {
          Console.WriteLine(“Method Test called with parameter ” + i);
      }

What happens when I do + and – operation on delegates.Internally the methods System.Delegate.Combine and System.Delegate.Remove is invoked by the runtime.This we can see in the IL code of the show demo method:

.method public hidebysig instance void  ShowDemo() cil managed
{

  …………..

  IL_0028:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
                                                                                          class [mscorlib]System.Delegate)
  ……………

  IL_0049:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,
                                                                                         class [mscorlib]System.Delegate)
  ……………..

} // end of method DelegateSample::ShowDemo

Advertisements
Comments
  1. pal b says:

    Nice article.

    Question – if the invocation list of a delegate contains more than 1 entry, then which entry will be pointed by Method and Target properties?

    • sankarsan says:

      Hi Palash,
      Thanx a lot for going through the post.
      To answer your question the instance of the combined delegate maintains an private object array _invocationList.This array contains the delegate objects added to the delegate using Combine method.
      The Method and Target properties of the combined delegate contains values as per the last entry in _invocationList array.

  2. pal b says:

    Yup, then we should always use GetInvocationList() method – right? I dont see any reason to use those two public attributes – Method & Target? Do you?

  3. Joydeep Sen says:

    hi palash,
    I think, as the Method and Target properties of the combined delegate contains values as per the last entry in _invocationList array so you dont see any reason to use those public properties.

    But when you call the GetInvocationList() method it will return array of Delegates.
    Now if you want to check the method and Target information for those methods encapsulated in the multicasting delgate definitely you need to use Method and targrt public peroperties.right?

    del is a multicasting delegate.
    Delegate[] delegates=del .GetInvocationList ( );
    foreach(Delegate dl in delegates)
    {
    Console .WriteLine ( dl .Method .Name );
    Console .WriteLine ( Environment.NewLine);
    Console .WriteLine ( dl .Target.ToString());
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s