Understanding Lambda Expressions                                                
•        C# 3.0 now supports the construction of lambda expressions.
•        In C#, lambda expressions are used to radically simplify the way we work with delegate types.
•        More specifically, lambda expressions are a simplification of C# 2.0 anonymous methods.
•        To this end, lambdas are always entirely optional, and nothing more than syntactic sugar (“You don’t
need it, but it makes your code more sweet”).
•        The current build of VB 9.0 does not yet support lambda syntax.
•        The final release of VB 9.0 will have limited lambda support, by defining new semantics for the Function
keyword.
•        Even so, VB’s initial support for lambda expressions will be limited and not as powerful as what we
currently find in C#.
•        Later releases should find VB’s lambda support to be on par w/ C# 3.0.  
•        Given these points, the following discussion is limited to C# code.
•        If you are a VB programmer, you will still be able to glean important information regarding the role of
lambdas.
•        This will prove useful with the final release of VB 9.0.

•        To understand the usefulness of lambda expressions, consider the .NET Predicate<T> generic delegate
type.
•        This delegate can ‘point to’ any method which returns a Boolean and takes a single T as input.
•        The List<T>.FindAll() method requires an instance of Predicate<T> as a parameter.
•        Using this delegate, we could build a program which finds all even numbers in an array of integers.
•        Here is the program in question, using traditional C# delegate syntax.
class Program
{
static void Main(string[] args)
{
List<int> list = new List<int>() {20, 1, 4, 8, 9, 44};   

// Create a Predicate<T> object for use by List<T>.
Predicate<int> callback = new Predicate<int>(CallMeHere);

// Call FindAll() using the delegate object.
List<int> evenNumbers = list.FindAll(callback);

// Print out the result set.    
Console.WriteLine("Here are the even numbers:");
foreach (int evenNumber in evenNumbers)
{
 Console.WriteLine(evenNumber);
}
}

// Target for the Predicate<T> delegate.
static bool CallMeHere(int i)
{
// Is it an even number?
return (i % 2) == 0;
}
}

•        One problem with traditional delegates is that they typically force us to build target methods (such as the
CallMeHere() function) which are only called by the delegate itself.
•        Under C# 2.0, anonymous methods provide a somewhat cleaner alternative, given that we can ‘inline’ the
delegate target.
•        Thus, the previous code could be remodeled as so:
static void Main(string[] args)
{
List<int> list = new List<int>() {20, 1, 4, 8, 9, 44};   

// Now, use an anonymous method.
List<int> evenNumbers = list.FindAll(delegate(int i)
{ return (i % 2) == 0; } );

Console.WriteLine("Here are the even numbers:");
foreach (int evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
•        While this example can be considered ‘better’, there are still some problems:
•        We are still required to use the delegate keyword (or a strongly typed Predicate<T>).
•        The parameter list must be a dead on match.

•        Now consider the same code retrofitted to use the C# lambda operator (=>).
•        In the code below, notice how there is no trace of the delegate type whatsoever.
•        Under the hood, the C# compiler generates an appropriate anonymous method.
static void Main(string[] args)
{
List<int> list = new List<int>() {20, 1, 4, 8, 9, 44};   

// Now, use a C# 3.0 lambda expression.
// Remember!  This is just an anonymous method in disguise!
List<int> evenNumbers = list.FindAll(i => (i % 2) == 0);

Console.WriteLine("Here are the even numbers:");
foreach (int evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}

•        To further simplify this example, we could infer the type using the new var keyword.
•        This keyword is handy when working with lambda expressions, given that they can typically return back
any number of return value types.
•        In this case the hidden Predicate<T> is returning a List<int>, however other lambdas could return
something completely different.
static void Main(string[] args)
{
// Now using implicit typing.
var list = new List<int>() {20, 1, 4, 8, 9, 44};   
var evenNumbers = list.FindAll(i => (i % 2) == 0);

Console.WriteLine("Here are the even numbers:");
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
Console.ReadLine();
}
•        A C# lambda expression consists of two aspects, separated by the lambda operator (=>).
•        To the left of the lambda operator is the set of arguments to process.
•        To the right of the lambda operator is the set of code statements which process the arguments in question.

•        In this case, the ‘argument to process’ is simply named ‘i’.
•        The ‘statements to process them’ is the same code logic we previously placed in the method called by the
delegate target.
•        And again, the lambda operator (=>) is nothing more than a shorthand notation for an anonymous method.
// Take the argument named 'i' and
// pass it to the statement (i % 2) == 0.
var evenNumbers = list.FindAll(i  => (i % 2) == 0);
•        Be aware that the name of the argument can be anything you desire.  
•        Arguments processed by a lambda expression can be understood as ‘normal’ parameters sent into a
‘normal’ function.
•        As you already know, when defining a function, you can name your parameters anything you wish.
•        For example, consider the following update.
var evenNumbers =
list.FindAll(itemToProcess => (itemToProcess % 2) == 0);
•        Currently, our lambda expression processes a single input argument against a single code statement.
•        However, a lambda expression can take multiple input arguments if required.
•        Furthermore, these arguments can be processed by numerous code statements.

•        When your arguments are processed by multiple code statements, they are grouped within curly brackets
to define their scope.
•        This lambda expression will evaluate the input argument (itemToProcess) against a set of statements:
// This time the lambda expression is build with a statement
// block.
var justATest = list.FindAll(itemToProcess => {
Console.WriteLine("Called by FindAll()!");
Console.WriteLine("value of itemToProcess is currently: {0}",
itemToProcess);
bool isEven = ((itemToProcess % 2) == 0);
return isEven;
} );

Console.WriteLine("Here are the even numbers:");
foreach (var evenNumber in justATest)
{
Console.WriteLine(evenNumber);
}
Copyright (c) 2008.  Intertech, Inc. All Rights Reserved.  This information is to be used exclusively as an
online learning aid.  Any attempts to copy, reproduce, or use for training is strictly prohibited.
Lambda Expressions
Table of Contents
Courseware
Training Resources
Tutorials