Click here to Skip to main content
13,593,913 members
Click here to Skip to main content
Add your own
alternative version


78 bookmarked
Posted 19 Jul 2006
Licenced CPOL

A Study of Delegates

, 19 Jul 2006
Rate this:
Please Sign up or sign in to vote.
An article on delegates in C#.


Many of us already have some idea of delegates. But let's go deep inside and examine how the CLR/runtime and the compiler interprets the delegates, and what happens when you declare and manipulate delegates.

A delegate is a reference type, thus it does not hold the actual value, rather it holds the address of an object residing somewhere in the heap. To make the understanding of delegates simple, compilers represent the delegates in a different way than how it is interpreted by the CLR/runtime. We will first study how the compiler exposes delegates, and then we will jump into some ground realities of delegates from the CLR/runtime perspective.

Delegates and .NET Compilers

To make life simpler, most .NET compilers symbolize delegates as pointers to a function, just like the function pointers we have in C++. Thus, in C#, you declare delegates as follows:

public delegate void MyDelegate (int someParam, string anotherParam);

From a C# compiler perspective, MyDelagate is a delegate that could hold the address of a function that has the similar signature.

The ability of holding the address of a function makes delegates ideal for:

  1. Callback functionality
  2. Event modeling
  3. Having more than one implementation against a method

Though the C# compiler exposes delegates as reference types, you could not instantiate the delegate by using the new operator; rather delegates could be instantiated by:

  1. Providing the name of the method to the delegate. These types of delegates are known as "Named Delegates".
    void DoSomething(int someParam, string anotherParam)
        //Method implementation
    MyDelegate del = DoSomething;
    //del is a Named Delegate holding 
    //the address of function DoSomething.
  2. Providing the implementation of the method to the delegate. These type of delegates are known as "Anonymous Delegates".
    del = delegate(int someParam, string anotherParam)
          { //Method implementation };

Invoking of named or anonymous delegates is same as calling the function:

Del (29, "some value");

Named Delegates

Named delegates could hold the address of instance methods as well as the address of static methods. If the return type of a method is inheriting from the return type defined in the delegate, then the delegate is known as a Covariance Delegate. If the parameters of the methods are the base types of the parameters defined in the delegate, then the delegate is known as a Contravariance Delegate.

public delegate ICollection MyDelegate (int someParam, 
                                 string anotherParam); 

IList DoSomething()
    //Method implementation

MyDelegate del = DoSomething;

//As IList is child of ICollection thus, 
//Del is covariance delegate.
public delegate ICollection MyDelegate (IList param);

IList DoSomething(ICollection param)
    //Method implementation

MyDelegate del = DoSomething;

//As IList is child of ICollection thus, 
//Del is contravariance delegate.

Anonymous Delegates

If an anonymous delegate is referring to some local variables, then the life of that variable would be extended to the life of that delegate.

public delegate void MyDelegate (int someParam, string anotherParam); 

MyDelegate del
void DoSomething()
    int n;
    del = delegate(int someParam, string anotherParam)
//In above example life of local variable n 
//would be same as life of anonymous delegate del.

Delegates and the CLR/Runtime

.NET compilers have made our life easy in handling delegates. In reality, there is neither any concept of pointers to a function nor any significance to the word "delegate" in the CLR/runtime. Rather, the CLR provides an abstract class System.Delegate that holds the reference of a static method or class instance and the instance method of that class. The System.Delegate has two properties.

  • Target: Holds the reference of an instance on which the current delegate invokes the instance method. If the method is a static method, this property holds a null value.
  • Method: Holds the instance of the MethodInfo class for the method represented by the delegate.

The delegate also exposes the DynamicInvoke function to call the method represented by the Method property. This function takes an array of objects that are the arguments to pass to the target method. If the target method does not take any arguments, the parameter to the DynamicInvoke function would be null.

The CLR also exposes an abstract class System.MultiCastDelegate that inherits from System.Delegate. System.MultiCastDelegate maintains a list, called the Invocation List, of a delegate object. When a multicast delegate is invoked, all the delegates in the invocation list are called synchronously. The System.MultiCastDelegate exposes the Combine method to add delegates to the invocation list.

When you define a delegate in C#, a new class with the name of the delegate inheriting from System.MultiCastDelegate is created by the C# compiler.

public delegate ICollection MyDelegate (IList param);

The above statement causes a a new class to be added in your assembly by the C# compiler.

public class MyDelegate : System.MultiCastDelegate

You can view this class by opening your assembly using the Ildasm utility.

When you assign a method to a delegate, an instance of the compiler generated class is created with the Target and Method as parameter to this class. In case the method is static, null is passed to the argument, Target.

As compiler generated classes are inheriting from System.MultiCastDelegate, thus delegate could hold the addresses of more than one method. C# exposes a simple method to add a method in the invocation list of underlying multiCast delegate object.

MyDelegate del;
del += DoSomething;
del += DoAnotherThing;

Internally, the C# compiler is calls the Combine method of the compiler-generated delegate class to add the methods to the invocation list.

When you invoke a delegate, C# internally calls the DynamicInvoke method of the compiler generated class. The compiler generated class also exposes methods to invoke the target methods asynchronously.

A delegate is known as an Open Instance Delegate if the Target is also provided at the time of invocation.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Tariq A Karim
Software Developer (Senior) RBS Bank
United Kingdom United Kingdom
Over 14 years of experience in enterprise / real-time software development using Microsoft Technologies.

More details in LinkedIn Or Blog

You may also be interested in...

Comments and Discussions

GeneralMy vote of 3 Pin
Member 328193824-Oct-14 16:07
memberMember 328193824-Oct-14 16:07 
GeneralMy vote of 5 Pin
yanghe16-Dec-10 15:57
memberyanghe16-Dec-10 15:57 
Generalask for IsAlive Pin
olivianer17-Oct-08 2:17
memberolivianer17-Oct-08 2:17 
Questiondelegates Pin
GopiRajendran21-Jan-07 19:46
memberGopiRajendran21-Jan-07 19:46 
QuestionWhat about delegate in .NET 2 Pin
Ahmed.net7-Dec-06 2:22
memberAhmed.net7-Dec-06 2:22 
AnswerRe: What about delegate in .NET 2 Pin
Tariq Karim9-Dec-06 7:42
memberTariq Karim9-Dec-06 7:42 
QuestionAbout Anonymous Delegates Pin
lenininy2k18-Sep-06 1:19
memberlenininy2k18-Sep-06 1:19 
AnswerRe: About Anonymous Delegates Pin
Tariq Karim19-Sep-06 9:32
memberTariq Karim19-Sep-06 9:32 
Anonymous delegate are similar to the normal delegate except that you define a function for the delegate. Rather in anonymous delegate, you define the implementation.

E.g if you want to handle the button click event, you can declare an anonymous delegate as follows:

button1.Click += delegate(System.Object o, System.EventArgs e)
System.Windows.Forms.MessageBox.Show("Oh...anonymous delegate is so simple.");

GeneralInvoking a delegate Pin
fcs3-Aug-06 0:23
memberfcs3-Aug-06 0:23 
Questionre: Am I missing something? Pin
James Wathen26-Jul-06 10:11
memberJames Wathen26-Jul-06 10:11 
QuestionAm I missing something ? Pin
James Wathen26-Jul-06 6:32
memberJames Wathen26-Jul-06 6:32 
AnswerRe: Am I missing something ? Pin
Tariq Karim26-Jul-06 9:41
memberTariq Karim26-Jul-06 9:41 
QuestionCan Instantiate a delegate using new operator Pin
Ved Kaila25-Jul-06 2:24
memberVed Kaila25-Jul-06 2:24 
AnswerRe: Can Instantiate a delegate using new operator Pin
Tariq Karim25-Jul-06 3:10
memberTariq Karim25-Jul-06 3:10 
Generaldelegates Pin
pjd100120-Jul-06 18:47
memberpjd100120-Jul-06 18:47 
GeneralRe: delegates Pin
Tariq Karim21-Jul-06 3:50
memberTariq Karim21-Jul-06 3:50 
GeneralHi Pin
ajai808520-Jul-06 4:42
memberajai808520-Jul-06 4:42 
GeneralRe: Hi Pin
Tariq Karim20-Jul-06 10:54
memberTariq Karim20-Jul-06 10:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03-2016 | 2.8.180618.1 | Last Updated 19 Jul 2006
Article Copyright 2006 by Tariq A Karim
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid