This article will explain about Lambda expression and its usage. This article will also give differences between Lambda expression and Anonymous method. This article will talk about type inference in Lambda expression. This will also talk about delegate type conversion of lambda expression.
We will start with a code. This is a very simple code which is printing Hello World. But this is done with help of Lambda Expression.
-
Lambda Expression provides a concise functional syntax for writing anonymous method.
-
It is a type safe way to write functions that can be passed as argument for subsequent evaluation.
-
Lambda expression are superset of anonymous method.
-
It can contain either and statement or an expression.
-
It may have or may not have parameters.
-
Its parameter could be implicitly or explicitly type.
-
It uses the lambda operator. => This operator is known as GOES TO
-
Different lambda expressions are
-
There are two types of Lambda expression
Expression LambdaA lambda expression, which is having expression at right hand side is called Expression lambda.
Examples:
Statement LambdaA lambda expression, which is having
statement at right hand side is called Statement lambda.
Examples:
Parameter types in Lambda Expression
-
For explicit type parameter, each parameter does have their type.
-
For implicit type parameter, type of parameter is inferred from compatible delegate type.
Working Example
See, the below code. How lambda expression is being used to find out name of the authors having more than 100 articles.
Output
Lambda Expression conversion to Compatible delegate type
Lambda expression is considered as a value, which is having special conversion rules. The Lambda expression value does not have a type but can be converted to compatible delegate type.
Let us suppose,
D-> Delegate
L-> Lambda Expression
Then D and L are called compatible if
-
D and L have same number of parameters.
-
If L has explicit type parameter then L should also have same type parameter list.
-
If L has implicit type parameter then L should not have Ref and Out parameters.
-
If D has a void return type and L is an expression type lambda expression then body of L is a valid expression and considered as a statement expression.
-
If D has a void return type and L is a statement type lambda expression then body of L is a valid statement block where no expression contains return statement.
-
If D is returning some type and L is an expression type lambda expression then body of L is a valid expression, if that is implicitly convertible to the return type of D.
-
If D is returning some type and L is a statement lambda expression then body of L is a valid statement body if in which each Return statement specifies the type which could be implicitly convertible to the return type of D.
Example
Let us suppose, there is a delegate
delegate void MyDelegate(int num);
Below lambda expression would work fine due to rule 5 stated above.
MyDelegate r = (num) => Console.WriteLine(num) ;
Below lambda expression would not work fine due to failure of rule 5 stated above.
Lambda Expression and Anonymous method
-
Lambda Expression permits parameter type to be omitted and inferred whereas anonymous method requires parameter type to be explicitly stated.
-
The body of lambda expression can be expression or statement whereas body of anonymous method only could be statement.
-
Lambda Expression within an expression body can be converted to expression tree.
Type inference in Lambda Expression
Let, we suppose we are assigning a value to a variable like below. Compiler will report an error "Cannot assign lambda expression to an implicitly typed local variable". Because c# type inference cannot be used to infer to infer type of a lambda expression.
This could be solved by, explicitly declaring the type of the lambda expression.
Func<int> res = () => 9;
For inferred return type of a lambda expression L is determined as follows:
-
If L is an expression type Lambda Expression, the type of that expression is the inferred return type of L.
-
If L is a statement type Lambda Expression, if the set formed by the types of the expressions in the block's return statements contains exactly one type to which each type in the set is implicitly convertible, and if that type is not the null type, then that type is the inferred return type of L.
-
Otherwise, a return type cannot be inferred for L.