Click here to Skip to main content
15,868,139 members
Articles / Programming Languages / C#
Article

Delegates in C #

Rate me:
Please Sign up or sign in to vote.
1.63/5 (25 votes)
8 May 20074 min read 43.5K   42   12
A tutorial on delegates

Introduction

A Delegate is a class. We create an object from this class. This object can be used to store a reference to a method. Once a reference to a method is stored in the delegate object, we can invoke the method using the delegate. Let's start to work with the Delegates. Let's go step by step. We will start with an empty class.

P1.cs

C#
class Del
{

}

Ok! Let's not compile yet. Now let's add a method to the above class. Let the name of the method be fn1(). This method will return a void. This method will accept no parameters. This method will display a line "Inside fn1".

This method will have access specifier as public. The program looks like this.

P1.cs

C#
class Del
{
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
} 

Now let's declare a delegate which will be responsible for storing the reference to the function fn1() we defined just now. Since the function fn1() accepts nothing and returns a void, the delegate reference we will declare will also be such that it accepts nothing and returns a void. So let's go ahead and declare a delegate reference dl1.

P1.cs

C#
class Del
{
    delegate void dl1();
    public void fn1()
    { 
        System.Console.WriteLine("Inside f1");
    }
} 

Now let's define a function fn2() which will make use of the delegate we declared. This function will accept nothing and returns a void. The program looks like this.

P1.cs

C#
class Del
{
    delegate void dl1();
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
    public void fn2()
    {
    }   
} 

Ok! Now let's add code to the above function to store the reference to the method fn1() into the delegate reference dl1's object. The program looks like this.

P1.cs

C#
class Del
{
    delegate void dl1();
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
    public void fn2()
    {
        dl1 obj = new dl1(fn1);
    }   
} 

Ok! Now let us invoke fn1() using the delegate object obj. The program looks like this.

P1.cs

C#
class Del
{
    delegate void dl1();
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
    public void fn2()
    {
        dl1 obj = new dl1(fn1);
        obj();
    }   
} 

Cool! Now let's add another class example and have the method Main() within it. The program looks like this.

P1.cs

C#
class Del
{
    delegate void dl1();
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
    public void fn2()
    {
        dl1 obj = new dl1(fn1);
        obj();
    }   
}
class Example
{
    public static void Main()
    {
    }
}

Now let us create an object of class Demo and add code to invoke the function Del::fn2() to check if the function Del::fn1() gets invoked via a call to delegate object obj(); The Program looks like this. Go ahead and compile and run the program.

P1.cs

C#
class Del
{
    delegate void dl1();
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
    public void fn2()
    {
        dl1 obj = new dl1(fn1);
        obj();
    }   
}
class Example
{
    public static void Main()
    {
        Del d = new DemoDeligates();
        d.fn2();
    }
}

OutPut

Inside
f1 

Ah! At last we got the desired output. Aren't delegates easy? Let's go though one more program if you found it hard to digest. Consider the following program.

P2.cs

C#
class Demo
{
    public static void Main()
    {
    }
}

In the above program we have a simple class Demo with a entry point method Main(). Let's add a simple function to it.

P2.cs

C#
class Demo
{
    public static void Main()
    {
    }
    public static void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
}

We have added a function named fn1 to the above program. Its job is to print "Inside f1". We want to invoke the function f1() using a delegate. So let's declare a delegate.

P2.cs

C#
class Demo
{
    delegate void d();
    public static void Main()
    {
    }
    public static void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
} 

We have declared a delegate d. Since delegate d will store the address of function f1() its prototype is like that of f1(). It accepts no arguments and returns a void.

Now let's create an object obj of declared delegate d. And in doing so pass the address of the function fn1, which we wish to invoke, to the constructor of d.

P2.cs

C#
class Demo
{
    delegate void d();
    public static void Main()
    {
        d obj = new d(fn1);
    }
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
} 

Now let us invoke fn1() using the object obj of delegate d.

P2.cs

C#
class Demo
{
    delegate void d();
    public static void Main()
    {
        d obj = new d(fn1);
        obj();
    }
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
}

Output

Inside
fn1 

The above program compiles and runs successfully to give the desired output. Wasn't that simple? But did you not wonder how are we allowed to use obj() when obj is not a function but an object? Well, the compiler is written in such a way that obj() is converted to obj.Invoke(). Don't believe it? Here is the proof.

P3.cs

C#
class Demo
{
    delegate void d();
    public static void Main()
    {
        d obj = new d(fn1);
        obj();
        obj.Invoke();
    }
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
}

Output

Inside
fn1

Inside
fn1 

The above program compiles and runs successfully to give the desired output.

Ok! Now consider the following program.

P3.cs

C#
class Demo
{
    delegate void d();
    public static void Main()
    {
        d obj = new d(fn1);
        obj();
    }
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
}

Output

Inside
fn1

The above program compiles and runs successfully to give the desired output. The delegate object obj is used to invoke fn1(). Let's add fn2() to the program.

P4.cs

C#
class Demo
{
    delegate void d();
    public static void Main()
    {
        d obj = new d(fn1);
        obj();
    }
    public void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
    public void fn2()
    {
        System.Console.WriteLine("Inside f2");
    }
}

Output

Inside
fn1

The above program compiles and runs successfully to give the desired output. Now what do we do to invoke fn2() as well using the delegate object obj? The following program shows this.

P5.cs

C#
class Demo
{
    delegate void d();
    public static void Main()
    {
        d obj = new d(fn1);
        obj();
        obj += new  d(fn2);
        obj();
    }
    public static void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
    public static void fn2()
    {
        System.Console.WriteLine("Inside f2");
    }
}

Output

Inside
fn1

Inside
fn1

Inside
fn2

The above program compiles and runs successfully to give the desired output. The statement that does the magic of adding method references to delegates is obj += new d(fn2);

Take the following program.

P6.cs

C#
class Demo
{
    delegate void d(int x);
    public static void Main()
    {
        d obj = new d(fn1);
        obj();
    }
    public static void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
}

Output

a.cs(7,14):
error CS0123: No overload for 'fn1' matches delegate 'Demo.d'

a.cs(3,17):
(Location of symbol related to previous error)

a.cs(11,22):
(Location of symbol related to previous error)

a.cs(8,6):
error CS1593: Delegate 'd' does not take '0' arguments

a.cs(3,17):
(Location of symbol related to previous error)

Bummer! We got an error! That's because we declared the delegate d to hold references of functions that return a void and accept an integer as an argument, whereas the function whose reference is being stored in the delegate d returns a void but also accepts no parameters. For the above program to run, the prototype for the delegate must match the prototype for the function. Modify the above program so that the delegate accepts no parameter to see it running.

P7.cs

C#
class Demo
{
    delegate void d();
    public static void Main()
    {
        d obj = new d(fn1);
        obj();
    }
    public static void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
}

Output

Inside
f1

Passing Delegates to functions

Can you pass delegates to functions? Yes. Why not? Let's see how we do this.

P8.cs

C#
class Demo
{
    delegate void del();
    public static void Main()
    {
        del obj = new del(fn1);
        foo(obj);
    }
    public static void fn1()
    {
        System.Console.WriteLine("Inside f1");
    }
    static void foo (del d) 
    {  
        d();
    }
}

Output

Inside
f1

The above program compiles and runs successfully to give the desired output. The delegate object obj is passed as an argument to function foo() which collects the delegate object obj in its formal argument d and invokes the functions whose references have been stored via the statement d();.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
India India
I am a Software engineer with around 7+ years of experience. Most of my experience is in Storage technology.

Comments and Discussions

 
QuestionOutput "Inside fn1" is wrong Pin
pauwau4-Jul-18 11:01
pauwau4-Jul-18 11:01 
GeneralMy vote of 1 Pin
David Pierson3-Nov-17 1:14
David Pierson3-Nov-17 1:14 
GeneralRe: My vote of 1 Pin
Chetan Kudalkar13-Nov-17 1:26
Chetan Kudalkar13-Nov-17 1:26 
ok..why is the class keyword used then ?
Chetan Kudalkar

QuestionThanks Pin
dattaram_garud21-Jan-13 23:50
dattaram_garud21-Jan-13 23:50 
GeneralMy vote of 3 Pin
Neeraj K Sharma4-Oct-12 3:08
professionalNeeraj K Sharma4-Oct-12 3:08 
GeneralMy vote of 3 Pin
gthiyagu14-Mar-12 3:49
gthiyagu14-Mar-12 3:49 
QuestionDelegates Pin
Fred Griggs8-Jan-08 17:20
Fred Griggs8-Jan-08 17:20 
QuestionWhat's the point? Pin
mirano9-May-07 22:22
mirano9-May-07 22:22 
AnswerRe: What's the point? Pin
Chetan Kudalkar9-May-07 22:45
Chetan Kudalkar9-May-07 22:45 
GeneralRe: What's the point? Pin
Marc Leger10-May-07 7:11
Marc Leger10-May-07 7:11 
GeneralRe: What's the point? Pin
Amr Elsehemy ®12-May-07 3:28
Amr Elsehemy ®12-May-07 3:28 
GeneralRe: What's the point? Pin
p1otro7-Jul-09 0:39
p1otro7-Jul-09 0:39 

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.