Sugary C#, part 3 – lambda expressions
November 9, 2011 in Programming
Part 1 explored a part of C#’s syntactic sugar I didn’t care for: LINQ syntax.
Part 2 explored a part of C#’s syntactic sugar, while I used a lot, that could be a source of confusion: var.
Today’s installment covers a syntactic sugar feature that was, to me, long overdue. It is largely responsible for making the LINQ syntax readable. Also, it makes anything involving an anonymous method less cumbersome to use: lambda expressions.
Simply put, lambda expressions are a C# shorthand for any anonymous method. They can be used practically anywhere the anonymous method delegate syntax for C# is required. Here is a simple example:
public int CalcFromDelegate(Func<int, int> func)
{
return func(50) * 4;
}
// calling with the delegate syntax
var result1 = CalcFromDelegate(delegate(int param) { return param + 5; });
// calling with the lambda expression syntax
var result2 = CalcFromDelegate(param => param + 5);
var match = (result1 == result2); // match should be *true*
So… what is going on here? Obviously, the example is meant to show that the two ways of calling the anonymous method are practically identical. How does the syntax work?
- Lambda expressions use the => token. Only lambda expressions use this token, so seeing that indicates there is a lambda expression present.
- The left side of the => token has the expression’s arguments. The argument types are inferred from usage, much like var can infer a declared identifier’s type from usage. In the above example, the left side has the param argument. Since it is being used in an anonymous method that wants a delegate of type Func<int, int> (which is a delegate that is a method of a a single input parameter of type int and returns an int), we can tell that param is type int.
- The right side of the => token is the method body. A lambda expression with a single statement and no curly braces ( { } ) is assumed to be the return value of the method. The above example simply has param + 5 after the =>, so the method just returns the result of that basic expression. No return keyword is required in this instance.
// assume listOfData is a enumerated type containing instances of a class
// called Person that includes a Name (string), Age (int), and Salary
// (double) properties
var result = listOfData
.Where(x => x.Name.StartsWith("John") && x.Age > 30)
.OrderBy(x => x.Salary)
.Select(x => new { Name = x.Name, Bonus = x.Salary * 0.10 });
// result is an enumerated anonymous type with properties Name and Bonus,
// sorted ascending by Salary, with People whose name starts with John
// and is over the age of 30
C# 3.5 (and 4.0) can infer the types of the variable x in each of the three lambda expressions (in this case, all three are of type Person). The OrderBy and Select methods are also generic methods, the compiler can infer their type from the return type of each lambda expression. The Where expression must return bool, and the return expression in the lambda used there is obviously bool. The code, even if you aren’t too familiar with LINQ and only had this introductory look at lambda expressions, is not too hard figure out:
- Use Where to filter the list. It runs the anonymous method for each Person instance, only keeping the ones where the return value of the lambda expression is true.
- With the filtered list, re-order (ascending by using the OrderBy method) it by the Salary value of each Person instance filtered in the previous call.
- Finally with the final filtered and ordered set, return a new enumerable set with some anonymous type instances, each only having the Name and their calculated Bonus. The Select method allows us to make new projections of a enumerable set (using anonymous types – which is another topic, for another day).
Now, what if we didn’t have lambda expressions? What if LINQ was available, but we had to use the delegate syntax? Lets look:
var result = listOfData
.Where(delegate(Person x) { return x.Name.StartsWith("John") && x.Age > 30; })
.OrderBy(delegate(Person x) { return x.Salary; })
.Select(delegate(Person x) { return new { Name = x.Name, Bonus = x.Salary * 0.10 }; });
var result = from x in listOfData
where x.Name.StartsWith("John") && x.Age > 30
orderby x.Salary
select new { Name = x.Name, Bonus = x.Salary * 0.10 };
This has an implied lambda expression syntax. The from statement defines the common parameter name (x for type Person) that will be used in the 3 lambda expressions for the where, orderby, and select clauses. I do not know if the delegate syntax is even available in the LINQ syntax for LINQ queries. Finally, beyond LINQ usage, you can simply use lambda expressions in most places where an anonymous delegate is required:
// declare a delegate in a class
delegate int SomeNumberFromString(string input);
// later in a method
SomeNumberFromString func = s => s.Length;
var result = func("what"); // result is 4
If the right side of the => token needs to have multiple lines, simply put it in a code block like in a normal method definition. If you need to return a value in this form, you must use the return keyword:
// declare a delegate in a class
delegate int SomeNumberFromString(string input);
// later in a method
SomeNumberFromString func = s =>
{
s += "SomeMoreLetters";
return s.Length;
};
var result = func("what"); // result is 19
Need multiple arguments? Delineate the arguments with a comma, and put them in parenthesis:
Func<int, string, double> method = (x, s) => (double) s.Length / x; var result = method(2, "hello"); // result is (double) 2.5
No arguments? Empty parenthesis says the lambda expression has no arguments:
Func<bool> method = () => true; var result = method(); // result is *true*
Finally, you can even use lambda expressions for code that has no return value (a void ”return”). In this case, the right side must always be a statement block (in curly braces):
Action<string> doSomething = x => { Console.WriteLine(x + " w00t!"); };
doSomething("yay"); // outputs to console: yay w00t!
Action doSomethingWithoutParam = () => { Console.WriteLine("w00t!"); };
doSomethingWithoutParam(); // outputs to console: w00t!
Lambda expressions are my favorite addition to C#. They make using anonymous methods significantly less of a hassle. I simply hated typing out the delegate syntax. Once you get use to the syntax, it is pretty easy to read and very concise.
Do you use lambda expressions much? Do you still rather use the classic delegate syntax for anonymous methods? Do you see a reason when you must use one or the other? Give me some feedback, I am interested on you opinions on the use of C#’s lambda expressions.
Now, we just need all browsers to support a lambda expression syntax for the various implementations of JavaScript.


