Next Page



Delegates and Events

If you are new to C# School
This is the 10th in the series of lessons of our C# School. The C# School is a kind of interactive learning platform where those who want to learn .NET with C# can find help and support. With one issue a week, describing some areas of the C# Programming Language with the Microsoft .Net Platform, this is not the same traditional passive tutorial where the author only writes and the reader only reads. There will be exercise problems at the end of each issue, which the reader is expected to solve after reading the issue. The solution to these problems will be provided in the next issue for testing purposes. There is also a dedicated message board attached with the school, where you can ask questions about the article, and the author will respond to your question within 2/3 days. You can send your suggestions, feedback or ideas on how these lessons can be improved to either the Author ( farazrasheed@acm.org)or the WEBMASTER ( info@programmersheaven.com).

For previous lessons: Lesson Plan
Today we will explore the concept of delegates and events. We will start out by looking at the idea behind delegates and will see how delegates are used in C#. Later, we will explore multicast delegates and their significance. Finally, we will learn about events and event handling mechanism in C# through delegates.

Delegates Basics
Delegates are references to methods. So far we have used references to objects, e.g. Stack st = new Stack();

Here st is a reference to an object of the Stack class type. Hence, each reference has two properties: 1. The type of object (class) the reference can point to. 2. The actual object referenced (or pointed to) by the reference.

Delegates are similar to object references, but are used to reference methods instead of objects. The type of a delegate is the type or signature of the method rather than the class. Hence a delegate has three properties: 1. The type or signature of the method that the delegate can point to 2. The delegate reference which can be used to reference a method 3. The actual method referenced by the delegate

Author's Note: The concept of delegates is similar to the function pointers used in C++.



1.The type or signature of the method the delegate can point to
Before using a delegate, we need to specify the type or signature of the method the delegate can reference. The signature of a method includes its return type and the type of parameters which it requires to be passed. For example:

int someMethod(string [] args)
Is the common signature of the Main() method of a C# programs defined as:

int Main(string [] args)
{
...
}


And for the following Add() method:

int Add(int a, int b)
{
    return a+b;
}


The signature will be:

int aMethod(int p, int q)
Which is also the signature of following Subtract() method:

int Subtract(int c, int d)
{
    return c-d;
}


It should be noticed from the above examples that the name of a method is not the part of its signature; the signature only involves its return type and parameters.

In case of delegates, we define the type of a delegate using the delegate keyword, e.g.

delegate int MyDelegate(int p, int q);
Here we have defined a delegate type with the name 'MyDelegate'. The reference of this delegate type can be used to point to any method which takes two integers as parameters and returns an integer value.

2.The delegate reference, that can be used to reference a method
Once we have defined a delegate type, we can set it to reference actual methods with matching signatures. A delegate reference can be declared just like an object reference. For example, a reference of type MyDelegate (defined above) can be declared as:

MyDelegate arithMethod;
The delegate reference arithMethod can now reference any method whose signature is identical to the signature of MyDelegate.

3.The actual method referenced by the delegate
The delegate reference can be made to reference any method with a matching signature by passing its name as the parameter of delegate:

arithMethod = new MyDelegate(Add);
Here, the arithMethod delegate reference is made to point to the Add() method by passing its name as a parameter to the delegate type (MyDelegate).

The last two steps can be merged together in a single statement, like this:-

MyDelegate arithMethod = new MyDelegate(Add);
Calling the actual method through its delegate
Once the delegate reference 'arithMethod' has been made to point to the Add() method, it can be used to call the actual method like this:-

int r = arithMethod(3, 4);
The complete source code of the program is presented below.

using System;
namespace CSharpSchool
{
    class Test
    {
        delegate int MyDelegate(int p, int q);
	static void Main()
	{
	    MyDelegate arithMethod = new MyDelegate(Add);
	    int r = arithMethod(3, 4);
	    Console.WriteLine("The result of arthmetic operation 
            `+' on 3 and 4 is: {0}",r);
	}
	static int Add(int a, int b)
	{
	    return a + b;
	}
}
}
The result of the above program will be

The result of arthmetic operation `+' on 3 and 4 is: 7
Press any key to continue


The above program can be changed so that the arithmetic operation can be selected by the user.

using System;
namespace CSharpSchool
{
    class Test
    {
        delegate int MyDelegate(int p, int q);
	static void Main()
	{
	    MyDelegate arithMethod = null;
	    Console.WriteLine("Which arithmetic operation you 
            like to perform on 3 and 4?");
	    Console.WriteLine("Press + for Add        ");
	    Console.WriteLine("Press - for Subtract   ");
	    Console.Write("Press m for Maximum Number ");
	    char choice = (char) Console.Read();
	    switch(choice)
	    {
	        case '+':
                    arithMethod = new MyDelegate(Add);
		    break;
		case '-':
		    arithMethod = new MyDelegate(Subtract);
		    break;
		case 'm':
		    arithMethod = new MyDelegate(Max);
		    break;
	    }
	    int r = arithMethod(3, 4);
	    Console.WriteLine("\nThe result of arithmetic 
            operation {0} on 3 and 4 is: {1}", choice, r);
	}
	static int Add(int a, int b)
	{
	    return a + b;
	}
	static int Subtract(int a, int b)
	{
	    return a-b;
	}
	static int Max(int c, int d)
	{
	    if(c>d)
		return c;
	    else
		return d;
	}
    }
}
Here we have defined three methods with the same signature; Add(), Subtract() and Max(). A delegate type called MyDelegate is defined so that its reference arithDelegate can point to any method with a matching signature. The delegate reference 'arithDelegate' is used to point out the particular method based on the user input at runtime. The sample output of the code is:

Which arithmetic operation you like to perform on 3 and 4?
Press + for Add
Press - for Subtract
Press m for Maximum Number -

The result of arithmetic operation - on 3 and 4 is: -1
Press any key to continue


Since, in the output above, the user pressed '-', the delegate reference is made to reference and call the Subtract() method. The above program shows that the same delegate reference can be used to point to various methods as long as their signature is same as the signature specified by the delegate type.

Confusion in terminology
Unfortunately, the same term 'delegate' is used for both 'delegate type' and 'delegate reference', which sometimes creates confusion in the reader's mind. For the sake of clarity, we are continuously using the term 'delegate type' and 'delegate reference' and will recommend the readers to also use these.


                     Next Page


  User Comments


Talon

(Report as abusive)
Easily understandable article
There are two points that could have been clarified:

1) In the code that asked for a selection (+, -, or m), there was no default in the switch statement. Does attempting to use a null delegate throw an exception? If so, what type?

2) The event handling code implied that the order of the methods added to the multicast delegate is the same order in which the methods are called when it fires. Is this guaranteed to be true, or is the order undefined?
Anonymous

(Report as abusive)
Beautifully Explained, thanks!
Beautifully Explained, thanks!
Jim Byrd, MCP

From Akron, Ohio
(Report as abusive)
Great Explanation of Delegates in C#
It is always nice to have several explanations of any complex thing and sometimes we need to study many or all of them before we understand. This is the best
text book style I have seen.
Faraz Rasheed

From Karachi, Pakistan
(Report as abusive)
Reply to two questions by Talon
Hi Talon,

1. If you did not provide any valid option in the +, -, Max example, the delegate will point to no mehtod and when we will try to call the methods through it, we will get the nullreferenceexception

2. Yes, it is guaranteed that methods will be called in the same order in which they were registered or added to the delegate

Regards,
Faraz
PS: Please put your questions your queries to the attached message boards as it is easier to track and reply to a certain question
Raj Bala

From Bangalore, India
(Report as abusive)
Great Explaination
Very good teaching style.
  View all   Rate and comment this article




 
Printer friendly version of the les_csharp_10_p1 page


Sponsored links

Check For Updates
Easily add update features to your applications. A complete .Net updating solution.
Build IT Knowledge with Current & Trusted Content
Helps Employees Develop & Hone New Technical Programming Skills. Sign Up & Get Full Access.
Check Out IT Certification Preparation Materials
Sign Up With SkillSoft & Get Access to Training Materials for Over 50 Professional Certifications.
Online Crash Analysis
Automatically capture customer crash data, no debugger required. Support for .NET, C++, OS X, Java.
.Net Localization in three simple steps (WYSIWYG)
Localize .Net, C#/C/C++ & Delphi apps visually. HTML, HTML Help, XML & databases. Try Sisulizer now!


Newsletter | Submit Content | About | Advertising | Awards | Contact Us | Link to us |
© 1996-2008 Community Networks Ltd All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited. Violators of this policy may be subject to legal action. Please read Terms Of Use and Privacy Statement for more information. Development by Synchron Data - .NET development.