C# 代码了解委托、匿名方法、Lambda 表达式和闭包本质
文本摘自: 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之前的范畴。