Shahid Riaz Bhatti

if(my.work == “Interesting” || my.availableTime > my.workHours) { this.blog.Post();}

Delegate in C Sharp

November 02
by Shahid Riaz Bhatti 2. November 2008 09:36

What is delegate:

Delegate is a class which holds a reference to a method or a function. Delegate has a signature and It can only address those method or function whose signature are compatibe with the delegate.

e.g. A Delegate with a void return type and taking a string parameter can only holds a reference to a method or function which is taking a string parameter and whose return type is void.

using System;
using System.Collections.Generic;
using System.Text;

namespace GenericDelegate
{
    class Program
    {
        // Declare a delegate taking a string parameter
        // and returning nothing (i.e. void)
        public delegate void MyDelegate(string param);

        static void Main(string[] args)
        {
            MyDelegate strTarget = new MyDelegate(StringTarget);
            // Invokde the method using the delegate
            strTarget.Invoke("Hello delegate");
        }
        static void StringTarget(string arg)
        {
            Console.WriteLine("arg in uppercase is: {0}", arg.ToUpper());
        }

    }
}

 

In the above example I have delcared a delegate  MyDelegate and invoked it in the main program. The target of this delegate is StringTarget. The code is self explanatory.

Generic Delegate:

The above example is limited for only those functions or methods which is taking a string parameter and whose return type is void. What if we need a delegate which can take parameter of any kind (i.e. int, string,float or any class)? The answer is Generic delegate. The example of the Generic delegate is given below:

 using System;
using System.Collections.Generic;
using System.Text;

namespace GenericDelegate
{
    class Program
    {
        // Declare a delegate


        public delegate void MyGenericDelegate<T>(T param);

        static void Main(string[] args)
        {
            MyGenericDelegate<string> strTarget = new MyGenericDelegate<string>(StringTarget);
            // Invokde the method using the delegate
            strTarget.Invoke("Hello Generic Delegate");

            MyGenericDelegate<int> strIntTarget = new MyGenericDelegate<int>(IntegerTarget);
            strIntTarget.Invoke(100);
        }
        static void StringTarget(string arg)
        {
            Console.WriteLine("arg in uppercase is: {0}", arg.ToLower());
        }
        static void IntegerTarget(int arg)
        {
            Console.WriteLine("Integer arg is: {0}", arg.ToString());
        }

    }
}



In the above example I have declared a delegate which is MyGenericDelegate. This delegate is taking a type of generic i.e. T. To understand the Generic delegate see the implementation in the main program. In the main program I invoked two methods by using this generic delegate. First time I gave it a target of a function which is taking a parameter of type string and second type an Integer. The Generic delegate can take any kind of parameter and can hold reference to any methods or function.

Generic delegate for Custom data type:

Generic delegate can holds a reference to a methods or function of custome data type. i.e. I can write a class (myCustomeClass) and then I can use my Generic delegate of last example which can holds a reference to a function or method which is taking a parameter of type myCustome class.

Now see the following example:

using System;
using System.Collections.Generic;
using System.Text;

namespace GenericDelegate
{
    class Shahid
    {
        private string firstName = string.Empty;

        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }
        private string lastName = string.Empty;

        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }

    }



    class Program
    {
        // Declare a delegate.

         public delegate void MyGenericDelegate<T>(T param);

        static void Main(string[] args)
        {
            MyGenericDelegate<string> strTarget = new MyGenericDelegate<string>(StringTarget);
            // Invokde the method using the delegate
            strTarget.Invoke("Hello Generic Delegate");

            MyGenericDelegate<int> strIntTarget = new MyGenericDelegate<int>(IntegerTarget);
            strIntTarget.Invoke(100);

            Shahid obj = new Shahid();
            obj.FirstName = "Shahid";
            obj.LastName = "Riaz";
            MyGenericDelegate<Shahid> CustomeDataTypedelegate = new MyGenericDelegate<Shahid>(DisplayMyName);
            CustomeDataTypedelegate.Invoke(obj);

        }
        static void StringTarget(string arg)
        {
            Console.WriteLine("arg in uppercase is: {0}", arg.ToLower());
        }
        static void IntegerTarget(int arg)
        {
            Console.WriteLine("arg in uppercase is: {0}", arg.ToString());
        }
        static void DisplayMyName(Shahid obj)
        {
            Console.WriteLine("My Name is :" + obj.LastName + ", " + obj.FirstName);
            object obj;
        }

    }
}


The above example is a modified version of my last example in which I wrote a generic delegate and then use that delegate to invoke two function (one for string and one for Int). In this modified version I have made some changes which are given below:

I wrote a class names "Shahid" and added two fields in it i.e. (firstName and lastName). Also I added two properties for these two fields which are FirstName and LastName.

I also wrote a new method which is taking parameter of type "Shahid".

In the main program I declared the object of class Shahid, and then used that object to set the values for first name and last name. Then I used the GenericDelegate to invoke the method "DisplayMyName" method.

How to Put Restriction on delegate:

In the Generic delegate example we are invoking methods which can take parameter of any type. (i.e. in example I am using generic delegate to invoke the methods which are taking parameters of type "string,Integer and a custome data type which is Shahid".

Now I want my generic delegate to invoke only those methods which are taking only reference type parameter. To accomodate this requirments I have to modify myGenericDelegate. At the moment my delegate is declared as follow:

public delegate void MyGenericDelegate<T>(T param);

Now I want to modify my delegate so that it can invoke only those methods or function which are taking only reference type parameter. So I will change above delegate like this:

public delegate void MyGenericDelegate<T>(T param) where T : class;

Similarly you can modify the delegate to invoke only those functions or methods which are taking only value type parameter. like this:

public delegate void MyGenericDelegate<T>(T param) where T : struct;

Regards,


Shahid Riaz Bhatti
kick it on DotNetKicks.com
Technorati Profile

Currently rated 3.0 by 4 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

C#

Comments

Add comment


(Will show your Gravatar icon)  

Enter the word
6499


biuquote
  • Comment
  • Preview
Loading



RecentComments

Comment RSS

Most comments

supplynflshop supplynflshop
51 comments
tiffany-bracelets tiffany-bracelets
39 comments
AVI to iPad AVI to iPad
36 comments