C# 3.0 Lambda Expressions replacing Anonymous Methods

C# 3.0 Lambda Expressions play an integral part of making the LINQ framework work.  However, even apart from LINQ, they stand alone quite nicely as a great replacement to C# 2.0 anonymous methods in terms of language syntax usability.  For example, consider this simple anonymous method:

  
personList.RemoveAll(delegate(Person person)  
{  
    return person.DateOfBirth.Year < 1980;  
});  

While anonymous methods were a great language addition in C# 2.0, the syntax could be confusing at times in terms of getting the delegate signature correct and the curly braces all lined up in the right place.  In C# 3.0 this exact snippet of code can be re-written with Lambda expressions in a much more readable 1 line of code:

  
personList.RemoveAll(p => p.DateOfBirth.Year < 1980);  

What's even more interesting here is that both snippets generate the EXACT same MSIL:

L000f: ldsfld class [mscorlib]System.Predicate1<class ConsoleApplication1.Person> ConsoleApplication1.Program::<>9__CachedAnonymousMethodDelegate2
L_0014: brtrue.s L_0029
L_0016: ldnull
L_0017: ldftn bool ConsoleApplication1.Program::<Main>b__0(class ConsoleApplication1.Person)
L_001d: newobj instance void [mscorlib]System.Predicate
1::.ctor(object, native int)
L
0022: stsfld class [mscorlib]System.Predicate1<class ConsoleApplication1.Person> ConsoleApplication1.Program::<>9__CachedAnonymousMethodDelegate2
L_0027: br.s L_0029
L_0029: ldsfld class [mscorlib]System.Predicate
1 ConsoleApplication1.Program::<>9_CachedAnonymousMethodDelegate2
L
002e: callvirt instance int32 [mscorlib]System.Collections.Generic.List1<class ConsoleApplication1.Person>::RemoveAll(class [mscorlib]System.Predicate1)

Notice the b__0 method - just like normal 2.0 anonymous methods the compiler is generating a hidden method behind the scenes to handle the delegate:

  
[CompilerGenerated]  
private static bool <Main>b__0(Person person)  
{  
    return (person.DateOfBirth.Year < 0x7bc);  
}

so I guess I just like the way the code becomes less verbose and easier to understand at the same time.  As an additional example, think about the ForEach() anonymous method on the List class in 2.0:

  
personList.ForEach(delegate(Person person)  
{  
    Console.WriteLine(person.ToString());  
});

While nice, I always felt like it would just be a lot easier to write that statement like this:

  
foreach (Person person in personList)  
{  
    Console.WriteLine(person.ToString());  
}  

But now, with Lambda expressions, we finally have syntax that truly is more concise without losing readability:

  
personList.ForEach(p => Console.WriteLine(p.ToString()));