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
public static void MyForEach
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
public static void DoIfMatch
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