I am pretty you all must have seen these delegates when writing code. IntelliSense shows methods that accepts Actions, Func<TResult> and some accepts Predicate<T>. So what are these? Let’s find out.
Let’s go by a simple example. I have following “Employee” class and it has a helper method which will return me a list of Employees.
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime Birthday { get; set; }
public int Age { get; set; }
public static List<Employee> GetEmployeees()
{
return new List<Employee>()
{
new Employee()
{
FirstName = "Jaliya",
LastName = "Udagedara",
Birthday = Convert.ToDateTime("1986-09-11")
},
new Employee()
{
FirstName = "Gary",
LastName = "Smith",
Birthday = Convert.ToDateTime("1988-03-20")
}
};
}
}
List<Employee> employees = Employee.GetEmployeees();
Action
Action series of delegates are pointers to methods which takes zero, one or more input parameters, and does not return anything.
Let’s consider List<T>.ForEach Method, which accepts a Action of type T. For my list of type Employee, it accepts a Action of type Employee.
Action |
static void CalculateAge(Employee emp)
{
emp.Age = DateTime.Now.Year - emp.Birthday.Year;
}
Action<Employee> empAction = new Action<Employee>(CalculateAge);
employees.ForEach(empAction);
foreach (Employee e in employees)
{
Console.WriteLine(e.Age);
}
This will print me the calculated age for each employee. With the use of Lambda Expressions, I can eliminate writing a separate method for calculating the age and put it straight this way.
employees.ForEach(e => e.Age = DateTime.Now.Year - e.Birthday.Year);
Func<TResult>
Func<TResult> series of delegates are pointers to methods which takes zero, one or more input parameters, and returns a value of the type specified by the TResult parameter.
For this let’s consider Enumerable.First<TSource> Method, which has a overloading method which accepts a Func.
Func |
In my scenario this particular method accepts Func which accepts a Employee and returns a bool value. For this let’s create a method which I am going to point my Func to. Following method accepts a employee and checks whether his/her FirstName is equal to “Jaliya” and returns true or false.
static bool NameIsEqual(Employee emp)
{
return emp.FirstName == "Jaliya";
}
Func<Employee, bool> myFunc = new Func<Employee, bool>(NameIsEqual);
Console.WriteLine(employees.First(myFunc).FirstName);
Console.WriteLine(employees.First(e => e.FirstName == "Jaliya").FirstName);
Predicate<T>
Predicate<T> represents a method that defines a set of criteria and determines whether the specified object meets those criteria.
For this let’s consider List<T>.Find Method which accepts a Predicate.
Predicate |
static bool BornInNinteenEightySix(Employee emp)
{
return emp.Birthday.Year == 1986;
}
Predicate<Employee> predicate = new Predicate<Employee>(BornInNinteenEightySix);
Console.WriteLine(employees.Find(predicate).FirstName);
Console.WriteLine(employees.Find(e => e.Birthday.Year == 1986).FirstName);
Func Vs. Predicate<T>
Now you must be wondering what is the difference between Func and Predicate. Basically those are the same, but there is a one significant difference.
Predicate can only be used point to methods which will return bool. If the pointing method returning something other than a bool value, you can’t use predict. For that, you can use Func. Let’s take a look at following method.
static string MyMethod(int i)
{
return "You entered: " + i;
}
The method accepts a integer value and returns a string. I can create the following Func and use it to call the above method.
Func<int, string> myFunc = new Func<int, string>(MyMethod);
Console.WriteLine(myFunc(3));
This will compile and print the desired output. But if you try to create a Predicate for this, you can’t.
I am uploading the sample to my SkyDrive. Do play around!.
Happy Coding.
Regards,
Jaliya
I am uploading the sample to my SkyDrive. Do play around!.
Happy Coding.
Regards,
Jaliya
No comments:
Post a Comment