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:
L_000f: ldsfld class [mscorlib]System.Predicate
1<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
1ConsoleApplication1.Program::<>9__CachedAnonymousMethodDelegate2
L_002e: callvirt instance int32 [mscorlib]System.Collections.Generic.List1<class ConsoleApplication1.Person>::RemoveAll(class [mscorlib]System.Predicate
1<!0>)
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
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()));