更新记录
转载请注明出处:https://www.cnblogs.com/cqpanda/p/16690958.html
2022年9月17日 发布。
2022年9月10日 从笔记迁移到博客。
在匿名函数的基础上删除delegate关键字
在参数列表和函数体之间添加=>符号
语法:
(parameters) => expression-or-statement-block
实例:
实例:
delegate int Transformer (int i); Transformer sqr = x => x * x;
Lambda表达式最终会转为delegate instance或者expression tree
本质上编译器通过编写私有方法并将Lambda表达式的代码移到该方法中来解析
在编译器内部,lambda表达式会被转为类型的private方法
编译器会将Lambda表达式转为:
一个委托的实例(A delegate instance)
一个表达式树(expression tree, of type Expression
如果有捕获的外部变量,则转为类的私有字段进行处理
Variables can also be captured by anonymous methods and local methods
注意:变量的捕获发生在运行阶段
A lambda expression that captures variables is called a closure
实例:
static void Main() { int factor = 2; Func<int, int> multiplier = n => n * factor; Console.WriteLine (multiplier (3)); // 6 }
捕获变量会在lambda方法被调用的时候才会被引用,而不是在lambda表达式定义的时候
实例:
int factor = 2; Func<int, int> multiplier = n => n * factor; factor = 10; Console.WriteLine (multiplier (3)); // 30
实例:最终输出333
Action[] actions = new Action[3]; for (int i = 0; i < 3; i++) { actions [i] = () => Console.Write (i); } foreach (Action a in actions) a(); // 333
实例:最终输出012
Action[] actions = new Action[3]; for (int i = 0; i < 3; i++) { int loopScopedi = i; actions [i] = () => Console.Write (loopScopedi); } foreach (Action a in actions) a(); // 012
When you capture an iteration variable in a for loop,
C# treats the iteration variable as though it were declared outside the loop
注意:foreach没有这个问题(C# 5.0+)
实例:
Action[] actions = new Action[3]; for (int i = 0; i < 3; i++) actions [i] = () => Console.Write (i); foreach (Action a in actions) a(); // 333
如果非要捕获for循环中的当时的值,可以使用临时变量(temporary variable)
实例:
Action[] actions = new Action[3]; for (int i = 0; i < 3; i++) { int loopScopedi = i; actions [i] = () => Console.Write (loopScopedi); } foreach (Action a in actions) a(); // 012
本地方法可以是递归的,自己调用自己
本地方法可以避免指定委托类型的混乱
本地方法的开销稍微少一点
Lambda表达式有隐式类型(参数Implicitly typed parameters)
Lambda表达式有表达式语法(Expression syntax)
匿名方法必须有语句块(statement block)
Lambda表达式可以编译为表达式树(expression tree, by assigning to Expression
匿名方法可以完全省略参数声明
实例:
delegate int Transformer (int i); Transformer sqr = delegate (int x) {return x * x;}; Console.WriteLine (sqr(3)); // 9
实例:省略参数声明
public event EventHandler Clicked = delegate { };
实例:事件监听函数使用匿名方法
// Notice that we omit the parameters: Clicked += delegate { Console.WriteLine ("clicked"); };
persons.Where(person => person.Name.ToUpper() == "INIGOMONTOYA");
Lambda expressions (and anonymous methods) are not intrinsically built in to the CLR
Rather, when the compiler encounters an anonymous function
it translates it into special hidden classes, fields, and methods that implement the desired semantics
The C# compiler generates the implementation code for this pattern so that developers do not have to code it themselves
表达式式
实现
x=>x
语句式
实现
(int x) = > { return x;}