All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => x * x is read "x goes to x times x." This expression can be assigned to a delegate type as follows:
delegate int del(int i);
static void Main(string[] args){ del myDelegate = x => x * x; int j = myDelegate(5); //j = 25}
To create an expression tree type:
using System.Linq.Expressions;
namespace ConsoleApplication1
{class Program{
static void Main(string[] args){
Expression< del > myET = x => x * x;} }}
The => operator has the same precedence as assignment (=) and is right-associative.
Lambdas are used in method-based LINQ queries as arguments to standard query operator methods such as Where.
When you use method-based syntax to call the Where method in the Enumerable class (as you do in LINQ to Objects and LINQ to XML) the parameter is a delegate type System..::.Func<(Of <(T, TResult>)>). A lambda expression is the most convenient way to create that delegate. When you call the same method in, for example, the System.Linq..::.Queryable class (as you do in LINQ to SQL) then the parameter type is an System.Linq.Expressions..::.Expression
A lambda expression with an expression on the right side is called an expression lambda. Expression lambdas are used extensively in the construction of Expression Trees. An expression lambda returns the result of the expression and takes the following basic form: (input parameters) => expression
The parentheses are optional only if the lambda has one input parameter; otherwise they are required. Two or more input parameters are separated by commas enclosed in parentheses: (x, y) => x == y
A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces: (input parameters) => {statement;}
delegate void TestDelegate(string s);
TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); }; myDel("Hello");
Lambdas with the Standard Query Operators have an input parameter whose type is one of the Func<(Of <(T, TResult>)>) family of generic delegates. The Func<(Of <(T, TResult>)>) delegates use type parameters to define the number and type of input parameters, and the return type of the delegate. Func delegates are very useful for encapsulating user-defined expressions that are applied to each element in a set of source data. For example, consider the following delegate type:
public delegate TResult Func
Type Inference in Lambdas When writing lambdas, you often do not have to specify a type for the input parameters because the compiler can infer the type based on the lambda body, the underlying delegate type. For most of the standard query operators, the first input is the type of the elements in the source sequence. So if you are querying an IEnumerable
The general rules for lambdas are as follows:
- The lambda must contain the same number of parameters as the delegate type.
- Each input parameter in the lambda must be implicitly convertible to its corresponding delegate parameter.
- The return value of the lambda (if any) must be implicitly convertible to the delegate's return type.
The following rules apply to variable scope in lambda expressions:
- A variable that is captured will not be garbage-collected until the delegate that references it goes out of scope.
- Variables introduced within a lambda expression are not visible in the outer method.
- A lambda expression cannot directly capture a ref or out parameter from an enclosing method.
- A return statement in a lambda expression does not cause the enclosing method to return.
- A lambda expression cannot contain a goto statement, break statement, or continue statement whose target is outside the body or in the body of a contained anonymous function.