C# 3.0 Lambda Expressions replacing Anonymous Methods

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:

L_000f: ldsfld class [mscorlib]System.Predicate`1 ConsoleApplication1.Program::<>9__CachedAnonymousMethodDelegate2
L_0014: brtrue.s L_0029
L_0016: ldnull
L_0017: ldftn bool ConsoleApplication1.Program::

b__0(class ConsoleApplication1.Person)
L_001d: newobj instance void [mscorlib]System.Predicate`1::.ctor(object, native int)
L_0022: stsfld class [mscorlib]System.Predicate`1 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.List`1::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

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()));

posted on Wednesday, August 15, 2007 9:21 PM Print

This article is part of the GWB Archives. Original Author: Steve Michelotti

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.