What Problem Does Delegates Solve in C#?

Many times in interviews we face the question, “What problem does delegates solve?” Even though we know how to create and use Delegates we can’t convince the interviewer. I have also searched a lot and found many articles, below is the summary based on my knowledge. Hope this will give readers an in-depth understanding on delegates.

What is delegate?

Delegate in C# represents function pointers. Delegates are examples of encapsulation. It will encapsulate reference to a method inside itself. You are free to put any method which matches signature and it will get called when your delegate will gets called.

Now let’s come to the point

Problem 1

We have a windows form, on that form I have a grid. Now we also have a user control and on UC we have one Button.

Note: I am not saying this problem will only get solved by delegates; rather delegates are helpful in such a situation.

Solution: I will use publisher and subscriber pattern in this case using Delegates.

Step 1: I will create a Delegate and Event under user control as mention below:

publicdelegatevoidButtonClickedEventHandler(objectsender,EventArgs e);

Step 2: Will expose the event on button click on UC as mention below:

  1. if (this.OnUserControlButtonClicked != null)  
  2. {  
  3.    this.OnUserControlButtonClicked(GetDataTable(), e);  
  4. }  
In place of SQL server I have created a temporary datatable for the same as shown below:
  1. privateDataTableGetDataTable()  
  2. {  
  3.     DataTable table = newDataTable();  
  4.     table.Columns.Add("Name"typeof(string));  
  5.     table.Columns.Add("Class"typeof(int));  
  6.     table.Columns.Add("Gender"typeof(char));  
  7.     table.Rows.Add("Nishant", 1, "M");  
  8.     table.Rows.Add("Mittal", 2, "M");  
  9.     return table;  
  10. }  
When user will click on the button, it will load the datatable and send on the main form, on which I have the grid.

Step 3: On form load I will create an object of user control, at it on the form and initialize its event as well as mention below:
  1. DataobjCntrol = newData();  
  2. objCntrol.OnUserControlButtonClicked+=newData.ButtonClickedEventHandler(objCntrol_OnUserControlButtonClicked);  
  4. this.panel1.Controls.Add(objCntrol);  
Step 4: And finally I will load the data in the grid when event will get called as mention below:
  1. voidobjCntrol_OnUserControlButtonClicked(object sender, EventArgs e)  
  2. {  
  3.    DataTabledt = (DataTable)sender;  
  4.    dgv_Btn.DataSource = dt;  
  5. }  
Problem 2

Abstract Pointer Problem: One of the major factors we need to consider during code is “Coupling”. The best example of Loosely Coupled code is “3 Tier Architecture and MVC”.

Let’s talk about problem now: Let say I want to create a basic calculator, the whole logic is written in my business layer, but still u need change UI based on functionality. Let say I have a functionality of summing of two numbers, now client wants subtraction of two numbers as well.

Issue: In that case I have to change my UI based on new functionality.

Solution: I have to write something in business layer so that I don’t have to change my UI again and again. Now the first thing triggered in my mind is Delegates. Let’s see the implementation below:

I have a calculator class as per user client requirement I have defined two functions SUM and Subtract in this. Now let say I have few new requirement i.e. Divide, Multiply etc. Now I have to change the UI (Program.cs) again and again this is called “Tight Coupling”. Again I am insisting you should always write “Loosely Coupled “Code.

Now how to overcome this problem.

To overcome this issue I have used delegates and change my class accordingly as mention below:
  1. publicclassBusinessLayer  
  2. {  
  3.     publicdelegateintSolveCalculatorIssue(int p, int q);  
  4.     publicint Sum(int a, int b)  
  5.     {  
  6.         return a + b;  
  7.     }  
  8.     publicintSubstract(int a, int b)  
  9.     {  
  10.         return a - b;  
  11.     }  
  12.     publicint Multiply(int a, int b)  
  13.     {  
  14.         return a + b;  
  15.     }  
  16.     publicint Divide(int a, int b)  
  17.     {  
  18.         return a - b;  
  19.     }  
  20.     publicSolveCalculatorIssueSolveIssue(stringoparationName)  
  21.     {  
  22.         SolveCalculatorIssueobjDelegate = null;  
  23.         if (oparationName == "ADD")  
  24.         {  
  25.             objDelegate = Sum;  
  26.         }  
  27.         elseif(oparationName == "SUBSTRACT")  
  28.         {  
  29.             objDelegate = Substract;  
  30.         }  
  31.         elseif(oparationName == "MULTILPY")  
  32.         {  
  33.             objDelegate = Multiply;  
  34.         }  
  35.         elseif(oparationName == "DIVIDE")  
  36.         {  
  37.             objDelegate = Divide;  
  38.         }  
  39.         returnobjDelegate;  
  40.     }  
  41. }  
Now by doing this I am making a call generic without any coupling with the actual method names like ‘Sum’ , ‘Subtract’ etc.

Few Important points regarding Delegates: 
  • Delegate encapsulates the method.
  • Delegates can be call for Asynchronous processingBy using ‘BeginInvoke’ and ‘EndInvoke’
  • In case you want to call the sequence of method delegates are best option.
  • You can use delegates with event in Publisher and Subscriber pattern.