Starting from C# 3.0, you can use lambda expressions to assign implementation code to delegates. lambda expressions and delegates (https:///article/) Directly related. When the parameter is a delegate type, you can use a lambda expression to implement delegate references.
static void Main() { string mid = ", middle part,"; Func<string, string> anonDel = param => { param += mid; param += " and this was added to the string."; return param; }; (anonDel("Start of string")); }
On the left of the lambda operator "=>" is the parameter list, and on the right is the implementation code of the method of the lambda variable.
1. Parameters
If the lambda expression has only one parameter, just write the parameter name, like the above code.
If you delegate to use multiple parameters, you need to put the parameter name in brackets:
Func<double, double, double> twoParams = (x, y) => x * y; (twoParams(3, 2));
You can add parameter types to variable names in parentheses:
Func<double, double, double> twoParamsWithTypes = (double x, double y) => x * y; (twoParamsWithTypes(4, 2));
2. Multiple lines of code
If the lambda expression has only one statement, there is no need for curly braces and return statements in the method block, because the compiler will add an invisible return statement.
Func<double, double, double> twoParams = (x, y) => x * y; Func<double, double, double> twoParams = (x, y) => { retrun x * y; }
If there are multiple statements in the implementation code of the lambda expression, you must add curly braces and return statements:
Func<string, string> anonDel = param => { param += mid; param += " and this was added to the string."; return param; };
3. Closure
The lambda expression allows access to variables outside the lambda expression block, which is called a closure. Closures are a great feature, but they can be dangerous if used incorrectly. For example:
int someVal = 5; Func<int,int> f = x => x+someVal;
Assume that the variable someVal is modified later, when delegate f is called, the new value of someVa will be used:
someVal = 7; f(3);//The result is10Instead8.
In particular, when calling a lambda expression through another thread, we may not know that this call was made, nor what the current value of the external variable is.
So be careful when using closures! ! !
When a lambda expression accesses variables outside the lambda expression block, when the compiler defines the lambda expression, the compiler creates an anonymous class that uses a constructor to pass the external variables. This constructor depends on the number and type of variables passed from outside.
For lambda expression Func<int,int> f = x => x+someVal;
public class AnonymousClass { private int someVal; public AnonymousClass(int someVal) { = someVal; } public int AnonymousMethod(int x) { retrun x+someVal; } }
When using a lambda expression and calling the method, an instance of the anonymous class is created and the value of the variable when the method is called is passed.
4. Use the closure of the foreach statement
Let’s take a look at the following example:
var values = new List<int>() {10,20,30}; var funcs = new List<Func<int>>(); foreach(var val in values) { (() => val); } foreach(var f in funcs) { ((f())); }
The first foreach statement adds each element in the funcs list. Functions added to the list use lambda expressions. The lambda expression uses a variable val, which is defined outside the lambda expression as a loop variable of the foreach statement. The second foreach statement iterates over the funcs list to call each function referenced in the list.
When this code is compiled before C# 5.0, it will output 30 three times on the console. This is because, in the first foreach loop, the created function is obtained when called, not when iterating. existhttps:///article/When introducing foreach, it says that the compiler will create a while loop from the foreach statement. In versions prior to C# 5.0, the compiler defined loop variables outside the while loop and reused this variable in each iteration. Therefore, at the end of the loop, the value of the variable is the value at the last iteration. To output 10, 20, 30 when using versions before C# 5.0, you need to change the code to use a local variable:
var values = new List<int>() {10,20,30}; var funcs = new List<Func<int>>(); foreach(var val in values) { var v = val; (() => v); } foreach(var f in funcs) { ((f())); }
In C# 5.0, this kind of code modification is no longer needed. C# 5.0 will create a different local loop variable in the while loop code.
This is all about this article about Lambda expressions in C#. I hope it will be helpful to everyone's learning and I hope everyone will support me more.