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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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();
.
I am a Software engineer with around 7+ years of experience. Most of my experience is in Storage technology.