Click here to Skip to main content
Click here to Skip to main content

Understanding Delegates in C#

By , 15 Sep 2005
Rate this:
Please Sign up or sign in to vote.

Introduction

Delegate is like a buzz word in C#.NET programming. In this article, I explain delegates, multicast delegates and their usage with the help of simple C# programs.

What is a Delegate?

Delegate is a type which  holds the method(s) reference in an object. It is also referred to as a type safe function pointer.

Advantages

  • Encapsulating the method's call from caller
  • Effective use of delegate improves the performance of application
  • Used to call a method asynchronously

Declaration

public delegate type_of_delegate delegate_name()

Example:

public delegate int mydelegate(int delvar1,int delvar2)

Note

  • You can use delegates without parameters or with parameter list
  • You should follow the same syntax as in the method
    (If you are referring to the method with two int parameters and int return type, the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer.)

Sample Program using Delegate

public delegate double Delegate_Prod(int a,int b);
class Class1
{
    static double fn_Prodvalues(int val1,int val2)
    {
        return val1*val2;
    }
    static void Main(string[] args)
    {
        //Creating the Delegate Instance
        Delegate_Prod delObj = new Delegate_Prod(fn_Prodvalues);
        Console.Write("Please Enter Values");
        int v1 = Int32.Parse(Console.ReadLine());
        int v2 = Int32.Parse(Console.ReadLine());
        //use a delegate for processing
        double res = delObj(v1,v2);
        Console.WriteLine ("Result :"+res);
        Console.ReadLine();
    }
}

Explanation

Here I have used a small program which demonstrates the use of delegate.

The delegate "Delegate_Prod" is declared with double return type and accepts only two integer parameters.

Inside the class, the method named fn_Prodvalues is defined with double return type and two integer parameters. (The delegate and method have the same signature and parameter type.)

Inside the Main method, the delegate instance is created and the function name is passed to the delegate instance as follows:

Delegate_Prod delObj = new Delegate_Prod(fn_Prodvalues);

After this, we are accepting the two values from the user and passing those values to the delegate as we do using method:

delObj(v1,v2);

Here delegate object encapsulates the method functionalities and returns the result as we specified in the method.

Multicast Delegate

What is Multicast Delegate?

It is a delegate which holds the reference of more than one method.

Multicast delegates must contain only methods that return void, else there is a run-time exception.

Simple Program using Multicast Delegate

delegate void Delegate_Multicast(int x, int y);
Class Class2
{
    static void Method1(int x, int y)
    {
        Console.WriteLine("You r in Method 1");
    }

    static void Method2(int x, int y)
    {
        Console.WriteLine("You r in Method 2");
    }

    public static void <place w:st="on" />Main</place />()
    {
        Delegate_Multicast func = new Delegate_Multicast(Method1);
        func += new Delegate_Multicast(Method2);
        func(1,2);             // Method1 and Method2 are called
        func -= new Delegate_Multicast(Method1);
        func(2,3);             // Only Method2 is called
    }
}

Explanation

In the above example, you can see that two methods are defined named method1 and method2 which take two integer parameters and return type as void.

In the main method, the Delegate object is created using the following statement:

Delegate_Multicast func = new Delegate_Multicast(Method1);

Then the Delegate is added using the += operator and removed using the -= operator.

Conclusion

This article would help to understand delegates in C# using simple examples. If you have any query regarding this article, you can reach me at arul_tony@yahoo.com.

History

  • 16th September, 2005: Initial post

License

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

About the Author

Arul Nayagam C
Web Developer
India India
Working as a Software Engineer in a MNC Company.Knowledge on C#.NET, ASP.NET, VB.NET ,VB & SQL Server.

Comments and Discussions

 
GeneralMy vote of 4 PinmemberAnimesh Datta10-Apr-14 23:07 
Generalthank you PinmemberHarikrishnanvr19-Mar-14 18:48 
Questiongood article Pinmembernikita123deshmukh10-Feb-14 19:25 
GeneralNice basic demo Pinmembersrinivas_here10-Feb-14 8:27 
GeneralMy vote of 1 PinmemberEbram Tharwat17-Dec-13 2:16 
GeneralGood article... [modified] PinmemberAtul Khanduri3-Dec-13 6:52 
QuestionCorrection to the second example PinmemberJohn Ortiz12-Oct-13 17:19 
QuestionBut whats the Need? PinmemberUpadhyay Praveen2-Jul-13 1:03 
AnswerRe: But whats the Need? PinmemberVishwanath Patil19-Jul-13 15:21 
AnswerRe: But whats the Need? [modified] PinmemberAtul Khanduri3-Dec-13 6:49 
GeneralMy vote of 3 PinmemberJorge Altamirano27-Jun-13 14:58 
QuestionNice PinmemberMember 26021227-Jun-13 3:11 
AnswerRe: Nice PinmemberAtul Khanduri3-Dec-13 10:08 
GeneralMy vote of 5 PingroupJohn Bracey6-Jun-13 10:07 
GeneralGood one for startup.... Pinmemberdeepakkarma13-May-13 0:14 
QuestionNice PinmemberKalaiselvanIT10-Apr-13 0:46 
AnswerRe: Nice PinmemberAtul Khanduri3-Dec-13 10:10 
GeneralMy vote of 3 Pinmembershantanu4coding5-Apr-13 1:02 
SuggestionBasics Of Delegates Pinmemberrajeev tapadar25-Mar-13 6:20 
GeneralRe: Basics Of Delegates PinmemberAtul Khanduri3-Dec-13 6:51 
GeneralMy vote of 5 Pinmembersymonsarwar21-Feb-13 5:55 
GeneralMy vote of 4 PinmemberDileepMada6-Feb-13 20:20 
QuestionMulticast Delegate PingroupRanjan Kumar Yadav25-Jan-13 7:03 
AnswerRe: Multicast Delegate PinmemberAtul Khanduri3-Dec-13 10:40 
GeneralMy vote of 5 PinmemberPraveenKumarReddyChinta7-Jan-13 22:25 
QuestionMulticast delegates must contain only methods that return void, else there is a run-time exception. PingroupWisen Technologies3-Jan-13 21:03 
GeneralMy vote of 4 PinmemberAdarsh Chaurasia2-Dec-12 19:24 
QuestionThanks Pinmemberumang_soni0126-Nov-12 22:56 
AnswerRe: Thanks PinmemberAtul Khanduri3-Dec-13 10:08 
GeneralMy vote of 5 PinmemberVikZ917-Nov-12 15:43 
GeneralMy vote of 3 Pinmemberkiransolkar30-Sep-12 23:48 
GeneralMy vote of 3 Pinmemberkiransolkar30-Sep-12 23:48 
GeneralMy vote of 5 PinmemberLee Venkatsamy13-Sep-12 11:52 
GeneralMy vote of 4 Pinmemberelaangovan19-Jul-12 1:21 
GeneralVery good Pinmemberambiste15-Jul-12 7:48 
GeneralMy vote of 5 Pinmemberajayendra270714-May-12 0:13 
GeneralUsefull PinmemberMaxAli26-Feb-12 0:19 
GeneralMy vote of 5 Pinmembervishakhakhadse23-Feb-12 20:46 
GeneralMy vote of 5 PinmemberAmol_Joshi27-Jan-12 5:34 
GeneralMy vote of 4 PinmemberJayanti12328-Dec-11 21:04 
GeneralMy vote of 5 PinmemberNitin Kurle21-Oct-11 20:26 
GeneralMy vote of 5 Pinmemberanuj178412-Sep-11 18:31 
GeneralMy vote of 1 Pinmembersarveshk.net21-Jul-11 0:27 
GeneralSimplest article on delegates! PinmemberMember 765836712-Mar-11 1:34 
GeneralMy vote of 3 PinmemberAshish96-Feb-11 18:17 
GeneralMy vote of 4 PinmemberChristy John31-Jan-11 0:01 
GeneralMy vote of 4 Pinmemberlokeshkumarn17-Sep-10 7:29 
GeneralMy vote of 3 Pinmemberchitizgaur31-Aug-10 20:15 
QuestionWhy use Delegates PinmemberTheArgyleGhost7-May-09 23:01 
AnswerRe: Why use Delegates PinmemberLee Venkatsamy13-Sep-12 11:50 
This answer is a few years late, but hope this helps others.
I asked myself the same question and realized a big advantage of using delegates.
Much like the English definition of a delegate, a C# delegate basically acts as the method you pass to it upon initialization, except now you can start passing your method to other methods much like a variable. This helps a lot with common Libraries & Generic Classes.
I used delegates today in a progress form library, and the code is something like this:
 
In the library:
 

public static class ProgressThreadHelper
{
    #region Delegates
 
    public delegate void DelegatePerformProgressStep(ProgressBar progressBar, Label label, string labelText);
 
    public delegate void DelegateSetProgressBar(ProgressBar progressBar, Label label, int maxValue,
                                                string labelText);
 
    #endregion
 
    private static Form _form;
    private static Delegate _delegate;
    private static object[] _objects;
    private static Thread _processPersonThread;
 
    internal static object Lock = new object();
 
    public static void StartWork(Form form, Delegate dDelegate, params object[] pObjects)
    {
        _form = form;
        _delegate = dDelegate;
        _objects = pObjects;
 
        StartThreading();
    }
 
    private static void StartThreading()
    {
        lock (Lock)
        {
            if (_processPersonThread == null || !_processPersonThread.IsAlive)
            {
                _processPersonThread = new Thread(() => _delegate.DynamicInvoke(_objects));
                _processPersonThread.Start();
            }
            else
            {
                MessageBox.Show("Still Processing this poes thing", "Be patient");
            }
        }
    }
 
    public static void PerformProgressStep(ProgressBar progressBar, Label label, string labelText)
    {
        _form.Invoke(
            new MethodInvoker(delegate
                                  {
                                      label.Text = labelText;
                                      progressBar.PerformStep();
                                  }));
    }
 
    public static void SetProgressBar(ProgressBar progressBar, Label label, int maxValue, string labelText)
    {
        _form.Invoke(
            new MethodInvoker(delegate
                                  {
                                      label.Text = labelText;
                                      progressBar.Value = 1;
                                      progressBar.Maximum = maxValue;
                                  }));
    }
 

}
 
And on the front end:
public partial class Form1 : Form
   {
       private const string PERSON_HEADER_LABEL = "Processing Person {0} of {1}";
       private const string PERSON_DETAIL_LABEL = "Processing Account {0} of {1} for Person {2}";
 
       public Form1()
       {
           InitializeComponent();
       }
 
       private void btnProcess_Click(object sender, EventArgs e)
       {
           ProgressThreadHelper.StartWork(this,
                                          new Action(
                                              () =>
                                              ProcessAccounts(ProgressThreadHelper.SetProgressBar,
                                                              ProgressThreadHelper.PerformProgressStep)));
       }
 
       public void ProcessAccounts(ProgressThreadHelper.DelegateSetProgressBar setProgressBar,
                                   ProgressThreadHelper.DelegatePerformProgressStep performProgressStep)
       {
           int noOfPeople = new Random().Next(5, 15);
 
           setProgressBar.Invoke(prgHeader, lblProcessHeader, noOfPeople,
                                 string.Format(PERSON_HEADER_LABEL, 0, noOfPeople));
 
           for (int i = 1; i <= noOfPeople; i++)
           {
               performProgressStep.Invoke(prgHeader, lblProcessHeader,
                                          string.Format(PERSON_HEADER_LABEL, i, noOfPeople));
 
               int noOfAccounts = new Random().Next(1, 5);
 
               setProgressBar.Invoke(prgDetail, lblProcessDetail, noOfAccounts,
                                     string.Format(PERSON_DETAIL_LABEL, 0, noOfAccounts, i));
 
               for (int j = 1; j <= noOfAccounts; j++)
               {
                   performProgressStep.Invoke(prgDetail, lblProcessDetail,
                                              string.Format(PERSON_DETAIL_LABEL, j, noOfAccounts, i));
 
                   Thread.Sleep(new Random().Next(150, 350));
               }
           }
 
           Invoke(
               new MethodInvoker(delegate
                                     {
                                         lblProcessHeader.Text = lblProcessDetail.Text = "Processed!!";
                                     }));
       }
   }
 
Its not the best implementation, but its something to see why delegates are useful.

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 16 Sep 2005
Article Copyright 2005 by Arul Nayagam C
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid