C#教程 - Lambda Expressions
更新记录
转载请注明出处:https://www.cnblogs.com/cqpanda/p/16690958.html
2022年9月17日 发布。
2022年9月10日 从笔记迁移到博客。
Lambda Expressions说明#
在匿名函数的基础上删除delegate关键字
在参数列表和函数体之间添加=>符号
语法:
(parameters) => expression-or-statement-block
实例:
实例:
delegate int Transformer (int i);
Transformer sqr = x => x * x;
更简化的Lambda#
Lambda本质#
Lambda表达式最终会转为delegate instance或者expression tree
编译器转换实现#
本质上编译器通过编写私有方法并将Lambda表达式的代码移到该方法中来解析
在编译器内部,lambda表达式会被转为类型的private方法
编译器会将Lambda表达式转为:
一个委托的实例(A delegate instance)
一个表达式树(expression tree, of type Expression
如果有捕获的外部变量,则转为类的私有字段进行处理
捕获外部变量(Capturing Outer Variables)#
说明#
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
捕捉for迭代变量(Capturing iteration variables)#
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表达式与本地方法(Lambda Expressions Versus Local Methods)#
比较#
本地方法可以是递归的,自己调用自己
本地方法可以避免指定委托类型的混乱
本地方法的开销稍微少一点
匿名方法(Anonymous Methods)#
Lambda表达式与匿名方法比较#
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"); };
实例:Using Lambda Expressions as Data#
persons.Where(person => person.Name.ToUpper() == "INIGOMONTOYA");
Anonymous Function Terminology plication#
Lambda表达式与编译器#
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
The Lambda Expression Tree Type#
分类#
表达式式
实现
x=>x
语句式
实现
(int x) = > { return x;}
作者:重庆熊猫
出处:https://www.cnblogs.com/cqpanda/p/16690958.html
版权:本作品采用「不论是否商业使用都不允许转载,否则按3元1字进行收取费用」许可协议进行许可。
本文来自博客园,作者:重庆熊猫,转载请注明原文链接:https://www.cnblogs.com/cqpanda/p/16690958.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律