Saturday, August 24, 2013

Lambda Expressions Explained


In this article I will take a simple Lambda expression and will show how this can be done using delegates (C# 1.0) and how Microsoft transitioned to the current syntax.

Definition

As per the MSDN documentation:

A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.

All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => x * x is read "x goes to x times x."

Simple Lambda Expression
 Lets have a list of employees which have EmployeeID & Name as shown below:

static List<Employee> lst = new List<Employee>() {  
                    new Employee() { EmployeeID=1, Name="Emp One"},
                    new Employee() { EmployeeID=2, Name="Emp Two"},
                    new Employee() { EmployeeID=3, Name="Emp Three"},
                    new Employee() { EmployeeID=4, Name="Emp Four"},
                    new Employee() { EmployeeID=5, Name="Emp Five"}
                    };

Then using Lambda expression we can find a specific employee as shown below:

var emp = lst.Find(e => e.EmployeeID == 3);

Using Delegates


In the absence of Lambda expressions the above functionality can be achieved by using delegates. First lets define a delegate to find an employee. Below is the signature of this delegate:

public delegate bool EmpFind(Employee emp);

Similar to the List.Find method, we will have our own find method which iterates through the list and call the delegate whether the current item matches the condition. The below code depicts our Find function.

public Employee Find(EmpFind findPredicate)
{
    foreach (Employee emp in lst)
    {
        if (findPredicate(emp))
            return emp;
    }
    return null;
}

Now we can call the above Find method and pass in our predicate as below:

Employee emp = Find(FindPredicate);
         
private bool FindPredicate(Employee e)
{
    if (e.EmployeeID == 4)
        return true;
    else
        return false;
}

In the above code we defined a FindPredicate function which matches our employee id. This predicate is passed as an input to the Find method.

Using Anonymous methods

C# 2.0 introduced anonymous methods which eliminated the need to define the function explicitly. Hence using anonymous methods the above Find method can be rewritten as:

Employee emp = Find(delegate(Employee e) {
                        if (e.EmployeeID == 4)
                            return true;
                        else
                            return false;
                    });

Using Anonymous Types & Lambda Expressions

Using C# 3.0 Anonymous types and Lambda expressions the above code can be simplified to

Employee emp = Find(e => {
                        if (e.EmployeeID == 4)
                            return true;
                        else
                            return false;
                    });

Using Lambda Expressions we can eliminate the if statement and reduce to the code as below:

Employee emp = Find(e => e.EmployeeID == 4);

Finally Microsoft predefined delegates that support simple operations similar to ours. Hence we don't need our delegate, instead we can use the Microsoft's delete as mentioned below:

public delegate TResult Func<in T, out TResult>(T arg)

References:


Lambda Expressions: http://msdn.microsoft.com/en-us/magazine/cc163362.aspx 
Func<T, TResult> Delegate: http://msdn.microsoft.com/en-us/library/bb549151.aspx
Further reading: http://www.codeproject.com/Articles/24255/Exploring-Lambda-Expression-in-C

No comments:

Post a Comment