Tuesday, October 11, 2011

Delegates

Hi EveryOne, in this blog i'm gonna give an simple example of how EXACTLY delegates works and how efficiently you can use them in your projects.

(Please correct me if i'm Wrong)

What is a delegate?
A delegate is a type safe function pointer. Using delegates you can pass methods as parameters. To pass a method as a parameter, to a delegate, the signature of the method must match the signature of the delegate. This is why, delegates are called type safe function pointers.

Delegates is one of the very important aspects to understand. Most of the interviewers ask you to explain the usage of delegates in a real time project that you have worked on.

Let me give an Example which can give you clear picture///

Delegates are extensively used by framework developers. Let us say we have a class called Employee as shown below.

Employee Class

using System;

public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int Experience { get; set; }
public int Salary { get; set; }


}


The Employee class has the following properties.
1. Id
2. Name
3. Experience
4. Salary

Now, I want you to write a method in the Employee class, which can be used to promote employees. The method should take a list of Employee objects as a parameter, and should print the names of all the employees who are eligible for a promotion. But the logic, based on which the employee gets promoted should not be hard coded. At times, we may promote employees based on their experience and at times we may promote them based on their salary or may be some other condition. So, the logic to promote employees should not be hard coded with in the method.

To achieve this, we can make use of delegates. So, now I would design my class as shown below. We also, created a delegate EligibleToPromote. This delegate takes Employee object as a parameter and returns a boolean. In the Employee class, we have PromoteEmpoloyee method. This method takes in a list of Employees and a Delegate of type EligibleToPromote as parameters. The method, then loops thru each employee object, and passes it to the delegate. If the delegate returns true, then them Employee is promoted, else not promoted. So, with in the method we have not hard coded any logic on how we want to promote employees.

using System;
using System.Collections.Generic;

//Declaring Delegate
public delegate bool EligibleToPromote(Employee EmployeeToPromote);

public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int Experience { get; set; }
public int Salary { get; set; }

//PromoteEmployee method
public static void PromoteEmployee(
List EmployeeList,
EligibleToPromote IsEmployeeEligible)
{
foreach (Employee employee in EmployeeList)
{
if (IsEmployeeEligible(employee))
{

HttpContext.Current.Response.Write(employee.Name);
}
}
}
}


So now, the client who uses the Employee class has the flexibility of determining the logic on how they want to promote their employees a shown below. First create the employee objects - E1, E2 and E3. Populate the properties for the respective objects. We then create an employeeList to hold all the 3 employees.



Notice, the private Promote method that we have created. This method has the logic on how we want to promote our employees. The method is then passed as a parameter to the delegate. Also note, this method has the same signature, as that of EligibleToPromote delegate. This is very important, because Promote method cannot be passed as a parameter to the delegate if the signature differs. This is the reason why delegates are called as type safe function pointers.

using System;
using System.Collections.Generic;

public partial class DelegateForm : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Manipulating Employee Records
Employee E1 = new Employee { Id = 101, Name = "Ramesh", Experience = 5, Salary = 2342 };
Employee E2 = new Employee { Id = 102, Name = "Ramesh1", Experience = 51, Salary = 23421 };
Employee E3 = new Employee { Id = 103, Name = "Ramesh2", Experience = 52, Salary = 23422 };
Employee E4 = new Employee { Id = 104, Name = "Ramesh3", Experience = 53, Salary = 23423};

//Creating List to store Employee details
List employeeList = new List();

//Adding the manipulated records to list
employeeList.Add(E1);
employeeList.Add(E2);
employeeList.Add(E3);
employeeList.Add(E4);
//Passing the employee list and private method
EligibleToPromote eligible = new EligibleToPromote(Promote);
Employee.PromoteEmployee(employeeList, eligible);

}

private static bool Promote(Employee employee)
{
if (employee.Salary >= 23421)
{
return true;
}
else
{
return false;
}
}
}


So if we did not have the concept of delegates, it would not have been possible to pass a function as a parameter. As Promote method in the Employee class makes use of delegate, it is possible to dynamically decide the logic on how we want to promote employees.

In C Sharp 3.0, Lambda expressions are introduced. So, you can make use of lambda expressions instead of creating a function, and then an instance of a delegate and then passing the function as a parameter to the delegate. The sample example rewritten using Lambda expressions is shown below. Private Promote method is no longer required now.

using System;
using System.Collections.Generic;

public partial class DelegateForm : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Manipulating Employee Records
Employee E1 = new Employee { Id = 101, Name = "Ramesh", Experience = 5, Salary = 2342 };
Employee E2 = new Employee { Id = 102, Name = "Ramesh1", Experience = 51, Salary = 23421 };
Employee E3 = new Employee { Id = 103, Name = "Ramesh2", Experience = 52, Salary = 23422 };
Employee E4 = new Employee { Id = 104, Name = "Ramesh3", Experience = 53, Salary = 23423};

//Creating List to store Employee details
List employeeList = new List();

//Adding the manipulated records to list
employeeList.Add(E1);
employeeList.Add(E2);
employeeList.Add(E3);
employeeList.Add(E4);
//Passing the employee list and private method
//EligibleToPromote eligible = new EligibleToPromote(Promote);
Employee.PromoteEmployee(employeeList, X => X.Experience >= 52);

}

//private static bool Promote(Employee employee)
//{
// if (employee.Salary >= 23421)
// {
// return true;
// }
// else
// {
// return false;
// }
//}
}


The output of the above program should be as below.
Ramesh2
Ramesh3

Hope this stuff helps you....