A lambda expression is an unnamed method written in place of a delegate
instance.
Given the following delegate type:
delegate int Converter (int i);
We could assign and invoke the lambda expression x => x * x as follows:
Converter sqr = x => x * x; Console.WriteLine (sqr(3)); // 9
A lambda expression has the following form:
(parameters) => expression
We can omit the parentheses if and only if there is exactly one parameter of an inferable type.
In our example, there is a single parameter,
x
, and the expression is x * x
:
x => x * x;
Each parameter of the lambda expression corresponds to a delegate parameter, and the type of the expression corresponds to the return type of the delegate.
In the code above, x
corresponds to parameter i
,
and the expression x * x
corresponds
to the return type int
, therefore it is compatible with the Converter
delegate
which is listed as follows:
delegate int Converter (int i);
A lambda expression's code can be a statement block instead of an expression.
x => { return x * x; };
Lambda expressions are used most commonly with the Func
and Action
delegates.
We can rewrite the above code as follows:
Func<int,int> sqr = x => x * x;
Here's an example of an expression that accepts two parameters:
Func<string,string,int> totalLength = (s1, s2) => s1.Length + s2.Length; int total = totalLength ("a", "the");
A lambda expression can reference the local variables and parameters of the method where it's defined.
For example:
static void Main(){
int factor = 2;
Func<int, int> multiplier = n => n * factor;
Console.WriteLine (multiplier (3)); // 6
}
Outer variables referenced by a lambda expression are called captured variables.
A lambda expression that captures variables is called a closure.
Captured variables are evaluated when the delegate is actually invoked, not when the variables were captured:
int factor = 2; Func<int, int> multiplier = n => n * factor; factor = 3; Console.WriteLine (multiplier (3)); // 6
Lambda expressions can update captured variables:
int outerVariable = 0; Func<int> myLambda = () => outerVariable++; Console.WriteLine (myLambda()); // 0 Console.WriteLine (myLambda()); // 1 Console.WriteLine (outerVariable); // 2
To write an anonymous method, include the delegate
keyword followed optionally
by a parameter declaration and then a method body.
For example, given this delegate:
delegate int Converter (int i);
We could write and call an anonymous method as follows:
Converter sqr = delegate (int x) {return x * x;}; Console.WriteLine (sqr(3)); // 9
The first line is semantically equivalent to the following lambda expression:
Converter sqr = (int x) => {return x * x;};
Or simply:
Converter sqr = x => x * x;
Anonymous methods capture outer variables in the same way lambda expressions do.