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

实例:

image

实例:

delegate int Transformer (int i);
Transformer sqr = x => x * x;

更简化的Lambda#

image

Lambda本质#

Lambda表达式最终会转为delegate instance或者expression tree

编译器转换实现#

本质上编译器通过编写私有方法并将Lambda表达式的代码移到该方法中来解析

在编译器内部,lambda表达式会被转为类型的private方法

编译器会将Lambda表达式转为:

​ 一个委托的实例(A delegate instance)

​ 一个表达式树(expression tree, of type Expression, representing the code inside the lambda expression in a traversable object model. This allows the lambda expression to be interpreted later at runtime)

​ 如果有捕获的外部变量,则转为类的私有字段进行处理

捕获外部变量(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#

image

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#

image

分类#

表达式式

​ 实现

​ x=>x

语句式

​ 实现

​ (int x) = > { return x;}

作者:重庆熊猫

出处:https://www.cnblogs.com/cqpanda/p/16690958.html

版权:本作品采用「不论是否商业使用都不允许转载,否则按3元1字进行收取费用」许可协议进行许可。

posted @   重庆熊猫  阅读(220)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示