Key concepts of Delegate using C#

ROMA CHAUHANProject Lead
CERTIFIED EXPERT
Published:
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that understanding with Experts-Exchange users.
What is delegate?
Delegate is like a function pointer in c++ means it holds the reference or address of the different methods. Those references can be changed runtime. We have to pass method name as the parameter at the time of instantiation.
Delegates are immutable. It means every time new object is created and fresh memory is allocated.

Types of delegate
There are two types of delegates.
  1. Single cast delegate – Delegate holds the reference of single method only
  2. Multi cast delegate – Delegate holds the references of multiple methods

How to declare or define delegate?
For example, we want to define the delegate which holds the reference of methods having string as return type and integer as input parameter then below will be the c# syntax for it.

internal delegate string MyTestDelegate(int InputValue);

Any method which matches the above delegate type can be assigned to this MyTestDelegate delegate.

How to create object of a delegate / instantiate delegate?
After declaring the delegate, we need to create the object of that delegate to assign the method as the parameter. For reference, I have created two methods NumberBetween1To10() and NumberBetween11To20() which takes integer value as input and return string parameter.
 
private string NumberBetween1To10(int InputValue)
                              {
                                  string strNumberInWords = string.Empty;
                                  if (InputValue >= 1 && InputValue <= 10)
                                  {
                                      strNumberInWords = "Number is inbetween 1 to 10";
                                  }
                                  return strNumberInWords;
                              }
                       
                      private string NumberBetween11To20(int InputValue)
                      {
                                  string strNumberInWords = string.Empty;
                                  if (InputValue >= 11 && InputValue <= 20)
                                  {
                                      strNumberInWords = "Number is inbetween 11 to 20";
                                  }
                                  return strNumberInWords;
                      }

Open in new window


On click of one button, we’ll call these two methods synchronously using delegate.
 
 private void btnSingleCast_Click(object sender, EventArgs e)
                              {
                                  MyTestDelegate objMyTestDel = new MyTestDelegate(NumberBetween1To10);
                                  objMyTestDel.Invoke(9);
                       
                                  objMyTestDel = new MyTestDelegate(NumberBetween11To20);
                                  objMyTestDel.Invoke(15);
                              }

Open in new window


In above example, we are creating the object objMyTestDel of MyTestDelegate type. To call those methods through delegate, we have to use Invloke() method of that delegate. Here both the methods will be executed one by one.
DelegateObject.Invoke() method will take the method parameters as argument.

Now you might have a question that, we can call these two methods directly by calling them on button click then what is the use of delegate over here.

What are the benefits of using delegate?

  • Useful to call methods synchronously (sequential) as well as asynchronously (parallel).
  • Callback method can be implemented
  • Multiple methods can be invoked using one delegate.

Asynchronous execution of method through delegate
In above example, we have executed methods using Invoke() method of the delegate. To call the methods asynchronously, we have to use the BeginInvoke() method of the delegate.

BeginInvoke() method will take input parameter, ASyncCallBack object, and object as argument.
 
MyTestDelegate objMyTestDel = new MyTestDelegate(NumberBetween1To10);
                      objMyTestDel.BeginInvoke(7, new AsyncCallback(CallBackMethod4NumBtwn1To10), null);
                       
                      objMyTestDel = new MyTestDelegate(NumberBetween11To20);
                      objMyTestDel.BeginInvoke(15, new AsyncCallback(CallBackMethod4NumBtwn1To10), null);

Open in new window


In above example, execution of first method will be started and after that second will be started. Second method will not wait for first method to complete the execution.

Callback method implementation
In above example, we came to know the parallel execution of the methods. In that code, we passed the callback method name in BeginInvole() method. Callback method will be executed after the completion of that particular method.
 
private void CallBackMethod4NumBtwn1To10(IAsyncResult CallBackResult)
                              {
                                  Console.WriteLine("Execution completed for NumberBetween1To10");
                              }
                       
                      private void CallBackMethod4NumBtwn11To20(IAsyncResult CallBackResult)
                              {
                                  Console.WriteLine("Execution completed for NumberBetween11To20");
                              }

Open in new window


When execution of NumberBetween1To10 is completed, the control comes to CallBackMethod4NumBtwn1To10 and the code written in that method will be executed. The same way it will executed for other methods.

Multicast Delegate

Multicast delegate is to call multiple methods using single delegate. Here delegate holds the references of multiple methods. Methods can be registered or unregistered using += and -= operators. In multicast delegate, all registered methods will be called with the same input parameter.
 
MyTestDelegate objMyTestDel = new MyTestDelegate(NumberBetween1To10);
                      objMyTestDel += new MyTestDelegate(NumberBetween11To20);
                      objMyTestDel.Invoke(10);

Open in new window


In above code snippet, two methods NumberBetween1To10() and NumberberBetween11To20() are registered with single delegate object objMyTestDel. Through single object of that delegate, both the methods will be called synchronously one after by another. Here the same parameter 10 will be passed to both the methods as input.

Asynchronous call is not possible in multicast delegate.
 
MyTestDelegate objMyTestDel = new MyTestDelegate(NumberBetween1To10);
                      objMyTestDel += new MyTestDelegate(NumberBetween11To20);
                      objMyTestDel += new MyTestDelegate(NumberBetween1To10);
                      objMyTestDel.Invoke(10);

Open in new window


If we run the above code snippet, the methods are executed in following manner.
NumberBetween1To10()--> NumberBetween11To20() --> NumberBetween1To10()
 
MyTestDelegate objMyTestDel = new MyTestDelegate(NumberBetween1To10);
                      objMyTestDel += new MyTestDelegate(NumberBetween11To20);
                      objMyTestDel += new MyTestDelegate(NumberBetween1To10);
                      objMyTestDel -= new MyTestDelegate(NumberBetween11To20);
                      objMyTestDel.Invoke(10);

Open in new window


In above code snippet, we are unregistering the method from the delegate using -= operator. The methods will be executed in following manner.
NumberBetween1To10() --> NumberBetween1To10()
KeyConceptsOfDelegateUsingC-.doc

 
2
2,888 Views
ROMA CHAUHANProject Lead
CERTIFIED EXPERT

Comments (2)

ROMA CHAUHANProject Lead
CERTIFIED EXPERT

Author

Commented:
Hi St. Jimbo,

Thanks for your valuable inputs.

As this is my very first article so I was not aware of all these points. I have submitted my article with the specified modifications.  Please review it again.


Thanks,
Roma
CERTIFIED EXPERT
Most Valuable Expert 2011
Top Expert 2015

Commented:
Any method which matches the above delegate type can be assigned to this MyTestDelegate delegate.
What do you mean by "matches"?

To call those methods through delegate, we have to use Invloke() method of that delegate.
You can also just invoke the delegate like a function using parentheses, which if memory serves is just syntactic sugar for Invoke:

objMyTestDel(9);
 
objMyTestDel(15);

Asynchronous execution of method through delegate
Don't forget about the async/await functionality of .NET!

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.