07 December 2014

Why to use delegates

Often this one of the questions you will be asked in C# .NET interview question. Then the usual answer is "Delegates are pointers to functions/methods" and "they are used to create events". There is nothing wrong with the answer but that is just a delegate definition. Now let's find the real convincing answer to the question, "Why delegates?"

Let's get started by creating a delegate in C# .NET Console application to understand Why Delegates.

public class Employee
{
 public delegate string EmployeeDisplayFormatter(Employee employee);

 public EmployeeDisplayFormatter DisplayFormatter;
 public string Name;
 public string Department;

 public override string ToString()
 {
  if (DisplayFormatter != null)
   {
     return DisplayFormatter(this);
   }
  return base.ToString();
  }
}

In the above Employee class, there is a delegate by name EmployeeDisplayFormatter. By definition, EmployeeDisplayFormatter delegate can point to any method which takes in Employee object as a parameter and returns a string value. If you look into Employee class ToString() method, it is invoking the delegate to get return value.

Advantage of using delegates

With delegates implementation, in future if you want to customize return value from the Employee's ToString() method you just need to pass different method implementation for same delegate.

  • Have a look at the console application example at the end of the post. Employee object's DisplayFormatter delegate is pointing to GetEmployeeDisplayNameWithDept1() method. So whenever Employee class ToString() method is used, you will get the return value depending on what is defined in the GetEmployeeDisplayNameWithDept1() method.

    static string GetEmployeeDisplayNameWithDept1
         (Employee employee)
    {
     return employee.Name + " works for " + employee.Department;
    }

    Employee employee = new Employee() { 
          Name = "Ranganath", Department = "IT" };
    employee.DisplayFormatter = GetEmployeeDisplayNameWithDept1;
    string displayText = employee.ToString();
    Console.WriteLine(displayText);

    Ranganath works for IT

  • Say for some other requirement you want change what what ToString() method returns. Using the delegate approach it has been made lot easier. Now you just need to Create a another method for your need matching the definition of the DisplayFormatter delegate.

    static string GetEmployeeDisplayNameWithDept2
       (Employee employee)
    {
       return employee.Name +" ("+ employee.Department+")";
    }

    Employee employee = new Employee() 
    { Name = "Ranganath", Department = "IT" };
    employee.DisplayFormatter = GetEmployeeDisplayNameWithDept2;
    string displayText = employee.ToString();
    Console.WriteLine(displayText);

    Ranganath(IT)

  • Without using the delegates here you had left with no option to modify Employee class to change what ToString() method returns each time your requirements changes. This formatting requirements are need is going change from time to time and from screen to screen in applications. So keeping this formatting logic outside the class by using delegates gives us the flexible design.

C# .NET program example showing why delegates

class Program
{
  static void Main(string[] args)
    {
       Employee employee = new Employee() 
           { Name = "Ranganath", Department = "IT" };

   employee.DisplayFormatter = GetEmployeeDisplayNameWithDept1;
   string displayText = employee.ToString();
   Console.WriteLine(displayText);
   Console.Read();
     }

   static string GetEmployeeDisplayNameWithDept1(Employee employee)
     {
       return employee.Name + " works for " +
       employee.Department;
     }

   static string GetEmployeeDisplayNameWithDept2(Employee employee)
     {
       return employee.Name +" ("+ employee.Department+")";
     }
 }

Hope now you understood when and why to use delegates. Please feel free to mention your comments!.

Also recently I posted another article to related delegates called Generic Delegates

No comments:

Post a Comment