Sunday, February 7, 2010

Lambda Expressions: A replacement to anonymous functions

I recently started looking at LINQ on .Net 3.5 and came across the concept of Lambda expressions and realized they are the perfect replacement to anonymous methods we used in .Net 2.0

Scenario:
Lets assume we have a room where there is some kind of celebration going on and we want to give some special gifts to all the senior citizens who have attended this celebration. So we add a list of people to the room (Joe, Kathie, Sam, etc..) and later we display a list of all senior citizens with their age so we can call out their names and give them the special gift.

Preparation:
  • Create a class that will store the name and age of a person.
  • Create a class which makes use of the above class as collection.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person()
    {   
    }
}

public class PeopleInRoom
{
    public List People = new List();
    public PeopleInRoom()
    {        
    }

    public IEnumerable SeniorCitizens20()
    {
        return People.FindAll(delegate(Person p) { return p.Age >= 60; }); //Uses anonymous method
    }

    //Lambda Expressions
    Func senior = p => p.Age >= 60;
    public IEnumerable SeniorCitizens35()
    {
        return People.Where(senior);        
    }
}

While implementing we have to create the list of people in a room and then filter it to have the names with their age who qualify as senior citizens (aged 60 or more).

Implementation:
protected void Page_Load(object sender, EventArgs e)
{
//Add people to the list
PeopleInRoom people = new PeopleInRoom();
people.People.Add(new Person("Joe", 50));        
people.People.Add(new Person("Kathie", 63));
people.People.Add(new Person("Sam", 59));
people.People.Add(new Person("John", 62));
people.People.Add(new Person("Aniada", 60));
people.People.Add(new Person("Alice", 49));

Response.Write("Using Anonymous Methods(2.0):
");
//Filter the list using anonymous method as predicate
foreach (Person p in people.SeniorCitizens20())
{
Response.Write(p.Name + " - " + p.Age.ToString() + "
"); //List the names along with age
}

Response.Write("
Using Lambda Expressions:
");
//Filter the list using Lambda expression as predicate
foreach (Person p in people.SeniorCitizens20())
{
Response.Write(p.Name + " - " + p.Age.ToString() + "
"); //List the names along with age
}
}

Explanation:
lets see the important sections in the above snippets of code
public IEnumerable SeniorCitizens20()
    {
        return People.FindAll(delegate(Person p) { return p.Age >= 60; }); //Uses anonymous method
    }
This is the section where we are using 2.0 anonymous method which you can pass as a delegate to filter the items in a collection. The same becomes much more easier with 3.5 and Lambda by declaring the predicate as a Lambda expression
Func senior = p => p.Age >= 60;
    public IEnumerable SeniorCitizens35()
    {
        return People.Where(senior);        
    }
The first line in the above snippet tells we have a object of type Person and the expression is going to return a Boolean and the name of the expression is senior. Further, the variable p is going to represent the object Person and the last part is the condition you are going to check which in our case is if the property Age has a value 60 or more. Just like we used predicates in .Net 2.0 we can use the Lambda expression as our predicate.

I found this new way of filtering collections quite interesting and thought of sharing my experience. I am looking forward to exploring .Net 3.5 more and try to blog my experiences which i feel are worth mentioning.

I hope this helps some if not all who are just starting to look at .Net 3.5 and its capabilities.

Happy Coding!!