.NET 3.5: Lambda Expressions

In addition to my first post about the new .NET 3.5 language features my second post in this series will be about Lambda Expressions. Lambda Expressions are basically a follow up to Anonymous Methods (in-line delegates), which were introduced in .NET 2.0. The advantage of Lambda Expressions over anonymous methods is that it is a superset of anonymous methods (more functionality) and that it provides a more concise, functional syntax for writing Anonymous Methods (C# 3.0 specification).

Based on the example of my Extension Methods post a foreach method, which takes a generic Action delegate as a parameter, can be created with an anonymous method. To invoke the SaySomething method for every Person object in the list you can write:

_persons.ForEach(delegate(Person p)
  {
    p.SaySomething("Hello");
  }
);

Using the Lambda Expression syntax this same code will be:

_persons.ForEach(
  p => p.SaySomething("Hello")
);

The syntax of param => expression is not only shorter and easier to read (once you are used to it), it is also implicitly typed. The type of p is inferred by the compiler and IntelliSense as a Person object, which is possible because the ForEach method is executed on a list of Person objects. The parameter p can also be explicitly typed by using the syntax (Person p) => p.Say…().

In this case, where the Lambda Expression takes one parameter and doesn’t have a return value, the definition of the method is with a parameter of the generic delegate type Action. So in case you want to write a method, e.g. as an IList extension, that takes these kind of Lambda Expressions you can write:

public static void MyForEach(this IList list, Action doFunc)

This method can be invoked exactly the same as the normal ForEach method, with either a delegate or a Lambda Expression. Of course a lot of other great constructions are possible, for example a DoIfMatch method that executes an action when there is a match found. Note that for the match function you use the generic delegate Func, where T is the type of the input parameter and R is the type of the result:

public static void DoIfMatch(this IList list, Func matchFunc, Action doFunc)

This method can be called using:

_persons.DoIfMatch(
  p => p.Name == "Person II",
  p => p.SaySomething("Hello")
);

In relation to LINQ Lambda Expressions are used in the Where-part and the OrderBy-part. There is a distinction however in LINQ implementations based on IEnumerable and IQueryable. The first one uses the Func delegates as explained above. The latter one however uses the Expression>, which makes evaluation of the Lambda Expression possible. This way LINQ to SQL, for example, can add the where part in de SQL query before it is send to the database. The Lambda Expression that you use in both cases aren’t any different though.