# Wisenheimer Brainstorm Wiki

### Site Tools

notes:csharp:lambda

# Lambda Expressions in C#

A lambda expression is a shorthand syntax for creating anonymous inline methods. Lambda expressions can be used whenever a delegate is used.

At compile time a lambda expression becomes either:

• an instance of a delegate
• or, an expression tree

Lambdas use the => notation, which can be read as “becomes” or “for which”.

### Examples

Func<int, int, int> f1 = (x, y) => x + y;
int n1 = f1(2, 2); // n1 == 4

Func<int, int, int> f2 = (x, y) => x * y;
int n2 = f2(7, 6); // n2 == 42

Func<int, int, string> f3 = (x, y) => (x * y).ToString();
string s1 = f3(8, 11); // s1 == "88"

Equivalent lambda expressions:

// A lambda expression with a statement block.
Func<string, int> f1 = (string str) =>
{
return str.Length;
};

// You can omit the braces if there is a single expression.
Func<string, int> f2 = (string str) => str.Length;

// You can omit the type of the parameter if the type can be implicitly inferred.
Func<string, int> f3 = (str) => str.Length;

// You can omit the parentheses if there is only one implicitly typed parameter.
Func<string, int> f4 = str => str.Length;

// The above lambda expressions are equivalent to the following code that creates
// a delegate instance using an anonymous method:
Func<string,int> f5 = delegate(string str) { return str.Length; };

Provide delegate instances for the ForEach, FindAll, and Sort methods as lambda expressions. ForEach, FindAll, and Sort are the extension methods on List<T>:

var numbers = new List<int> { 8, 5, 13, 4 };

Action<int> print = n => Console.Write("{0} ", n);

// The ForEach method takes an Action<T>.
numbers.ForEach(print); // 8 5 13 4

// The FindAll method takes a Predicate<T>.
numbers.FindAll(n => n < 8).ForEach(print); // 5 4

// The Sort method takes a Comparison<T>.
numbers.Sort((n1, n2) => n1.CompareTo(n2));
numbers.ForEach(print); // 4 5 8 13

Implement event handlers using lambda expressions:

// btnSave is a button on a page.
public InitPage()
{
{
// ...
};

btnSave.Click += (sender, args) => SaveData("Click", sender, args);
}

void SaveData(string eventName, object sender, EventArgs args)
{
// ...
}

### Closures

A lambda expression that captures variables is called a closure. A closure gives an ability for a lambda expression to interact with an environment beyond the parameters provided to it. A captured variable lives for at least as long as any function referring to it.

Example: Access a variable 'a' outside of the block of a lambda expression:

int a = 8;

Func<int, int> f = x => x + a;

Console.WriteLine(f(5)); // 5+8=13
a = 10;
Console.WriteLine(f(5)); // 5+10=15
...
{
// 'a' is alive here too
Console.WriteLine(q(7)); // 7+10=17
}

Example: Return a closure from a method.

static Func<int> Counter()
{
// n is a captured variable.
int n = 0;
return () => ++n; // returns a closure
}
...
Func<int> f = Counter();
Console.WriteLine(Counter()); // 1
Console.WriteLine(Counter()); // 2

Example: Outer, local, captured, and uncaptured variables:

// 'o' is an outer uncaptured variable.
// The variable is 'outer' because the anonymous method is declared within its scope.
int o = 0;

// 'a' is an outer captured variable because the anonymous method refers to it.
int a = 5;

Func<int, int> f = x =>
{
// 'b' is a local variable to the anonymous method.
// 'b' is created on the stack when the delegate
// instance (in this case the lambda expression) is executed.
int b = 3;

return x + a + b;
};

// Execute the lambda. This captures the variable 'a' itself rather than merely its value!
Console.WriteLine(f(2)); // 2 + 5 + 3 = 10

// Change the value of the captured variable 'a'.
a = 10;

// The change of the value of the variable 'a' is visible within the anonymous method.
Console.WriteLine(f(20)); // 20 + 10 + 3 = 33