CSharp Basic Tutorial hapter-4-4 Lambda 表达式


什么是Lambda表达式

Lambda表达式其实就是一个用来代替委托实例的未命名的方法;
编译器会把Lambda表达式转化为以下二者之一:

  • 一个委托实例
  • 一个表达式树(expression tree),类型是Expression,它表示了可遍历的对象模型中Lambda表达式里面的代码。它允许lambda表达式延迟到运行时再被解释。

whatlambda

  • 实际上,编译器会通过编写一个私有方法来解析这个lambda表达式,然后把表达式的代码移动到这个方法里。

Lambda表达式的形式

  • (parameters) => expression-or-statement-block
  • (参数)=> 表达式或语句块
  • 其中如果只有一个参数并且类型可推断的话,那么参数的小括号可以省略

lambda表达式与委托

  • 每个lambda表达式的参数对应委托的参数
  • 表达式的类型对应委托的返回类型
x => x * x;
delegate int Transformer(int i);

Lambda表达式 – 语句块

  • Lambda表达式的代码也可以是语句块
x => {return x * X};

Func 和 Action

  • Lambda表达式通常与Func和Action委托一起使用

functionAction

显式指定Lambda表达式的参数类型
lambdademo1
lambdademo2

捕获外部变量

  • lambda表达式可以引用本地的变量和所在方法的参数

capture1

被捕获的变量

  • 被Lambda表达式引用的外部变量叫做被捕获的变量(captured variables)。
  • 捕获了外部变量的lambda表达式叫做闭包。
  • 被捕获的变量是在委托被实际调用的时候才被计算,而不是在捕获的时候。

capture2

  • Lambda表达式本身也可以更新被捕获的变量

capture3

  • 被捕获的变量的生命周期会被延长到和委托一样

capture4

捕获迭代变量

  • 当捕获for循环的迭代变量时,C#会把这个变量当作是在循环外部定义的变量,这就意味着每次迭代捕获的都是同一个变量。

capture5

如何解决
how

注意:foreach

  • C#4,和C#5+的区别

foreach

Lambda表达式 vs 本地方法

本地方法是C#7的一个新特性。它和Lambda表达式在功能上有很多重复之处,但它有*三个优点:

  • 可以简单明了的进行递归
  • 无需指定委托类型(那一堆代码)
  • 性能开销略低一点

本地方法效率更高是因为它避免了委托的间接调用(需要CPU周期,内存分配)。本地方法也可以访问所在方法的本地变量,而且无需编译器把被捕获的变量hoist到隐藏的类。

匿名方法 vs Lambda表达式

匿名方法和Lambda表达式很像,但是缺少以下三个特性:

  • 隐式类型参数
  • 表达式语法(只能是语句块)
  • 编译表达式树的能力,通过赋值给Expression

lambdaExpression

匿名方法 - 其它

  • 捕获外部变量的规则和Lambda表达式是一样的。
  • 但匿名方法可以完全省略参数声明,尽管委托需要参数
public event EventHandler Clicked = delegate{};
  • 这就避免了触发事件前的null检查
//Notice that we omit the parameters:
Clicked += delegate {Console.Write("Clicked");};

文章作者: Chaoqiang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Chaoqiang !
评论
 上一篇
CSharp Basic Tutorial Chapter-4-5 Try 语句和异常 CSharp Basic Tutorial Chapter-4-5 Try 语句和异常
Try 语句 try语句指定了用来进行错误处理或清理的一个代码块。 try语句块后边必须紧接着一个catch块或者是一个finally块,或者两者都有。 当try块里发生错误的时候,catch块就会被执行。 finally块会在执行完t
下一篇 
CSharp Basic Tutorial Chapter-4-3 事件 CSharp Basic Tutorial Chapter-4-3 事件
Event 事件 使用委托的时候,通常会出现两个角色,一个广播者,一个订阅者 广播和订阅 使用委托的时候,通常会出现两个角色,一个广播者,一个订阅者 广播者这个类型包含一个委托字段,广播者通过调用委托来决定什么时候进行广播。 订阅者是方
  目录