C# 代码了解委托、匿名方法、Lambda 表达式和闭包本质

时间:2022-05-23 19:12:10

文本摘自: http://www.cnblogs.com/max198727/p/3436220.html

1. 三种实现委托的方法

下面先从一个简单的例子比较命名方法,匿名方法和 Lambda 表达式三种实现委托的方法

(1)申明一个委托,当然这只是一个最简单的委托,没有参数和返回值,所以可以使用Action 委托

1 delegate void DelegateTest();

(2)创建一个静态方法,以作为参数实例化委托

1 static void DelegateTestMethod()
2 {
3     System.Console.WriteLine("命名方式");
4 }

(3)在主函数中添加代码

 1 //命名方式
 2 DelegateTest dt0 = new DelegateTest(DelegateTestMethod);
 3 //匿名方法
 4 DelegateTest dt1 = delegate()
 5 {
 6     System.Console.WriteLine("匿名方法");
 7 };
 8 //Lambda 表达式
 9 DelegateTest dt2 = ()=>
10 {
11     System.Console.WriteLine("Lambda 表达式");
12 };
13 dt0();
14 dt1();
15 dt2();
16 System.Console.ReadLine();

输出:
  命名方式
  匿名方法
  Lambda 表达式

说明

通过这个例子可以看出,三种方法中命名方式是最麻烦的,代码也很臃肿,而匿名方法和 Lambda 表达式则直接简洁很多。这个例子只是实现最简单的委托,没有参数和返回值,事实上 Lambda 表达式较匿名方法更直接,更具有表达力。

那么 Lambda 表达式除了书写方式和匿名方法不同之外,还有什么不一样的地方吗?

无论是用匿名方法还是Lambda 表达式实现的委托,其本质都是完全相同。他们的原理都是在C#语言编译过程中,创建了一个静态的方法实例委托的对象。也就是说匿名方法和Lambda 表达式在CIL中其实都是采用命名方法实例化委托。

2. 研究带有参数的委托

2.1 研究采用匿名方法实现委托的方式,将代码改为:

1)将委托改为

1 delegate void DelegateTest(string msg);

2)将主函数改为

1 DelegateTest dt = delegate(string msg)
2 {
3     System.Console.WriteLine(msg);
4 };
5 dt("Just for test");

输出结果

  Just for test

2.2 研究采用 Lambda 表达式实现委托的方式,将代码改为:

1)定义一个委托

1 delegate void DelTest(int n);

2)在主函数中添加中添加代码

1 int t = 10;
2 DelTest delTest = (n) =>
3 {
4     System.Console.WriteLine("{0}", t + n);
5 };
6 delTest(100);

输出结果

  110

结论

C#在实现匿名函数(匿名方法和Lambda 表达式),是通过隐式的创建一个静态方法或者类(需要捕获变量时),然后通过命名方式创建委托。

本文到这里笔者已经完成了对匿名方法,Lambda 表达式和闭包的探索, 明白了这些都是C#为了方便用户编写代码而准备的“语法糖”,其本质并未超出.Net之前的范畴。