委托、Lambda表达式、事件系列03,从委托到Lamda表达式
在"委托、Lambda表达式、事件系列02,什么时候该用委托"一文中,使用委托让代码简洁了不少。
namespace ConsoleApplication2{
internal delegate bool MyCalculateDelegate(int val); class Program { static void Main(string[] args) { IEnumerable<int> source = new List<int>(){2, 3, 4, 5, 6, 7, 8, 9,10, 11}; MyCalculateDelegate del = LessThanFive; var result = GetNumbers(source, del); foreach (int n in result) { Console.WriteLine(n); } } static IEnumerable<int> GetNumbers(IEnumerable<int> numbers, MyCalculateDelegate del) { foreach (int number in numbers) { if (del(number)) yield return number; } } static bool LessThanFive(int val) { return val < 5; } static bool LessThanTen(int val) { return val < 10; } }}
可是,以上LessThanFive方法和LessThanTen方法的输入参数、输出类型、以及实现逻辑都是一致的,有没有一种形式可以替代它们?这正是Lambda表达式登场的时候!Lambda表达式是匿名委托,以=>分隔,左边是输入参数,右边是实现过程。
namespace ConsoleApplication2{
internal delegate bool MyCalculateDelegate(int val); class Program { static void Main(string[] args) { IEnumerable<int> source = new List<int>(){2, 3, 4, 5, 6, 7, 8, 9,10, 11}; var result = GetNumbers(source, n => n < 5); foreach (int n in result) { Console.WriteLine(n); } } static IEnumerable<int> GetNumbers(IEnumerable<int> numbers, MyCalculateDelegate del) { foreach (int number in numbers) { if (del(number)) yield return number; } } }}
以上,使用Lambda表达式又让代码简洁了不少!GetNumbers的实参n => n < 5,就是一个Lambda表达式,它符合委托MyCalculateDelegate的定义,输入参数是整型,输出是bool类型。
其实,lambda表达式n => n < 5是一种"语法糖",内部还是执行了如下代码:
...... MyCalculateDelegate del = LessThanFive; var result = GetNumbers(source, del); ...... static bool LessThanFive(int val) { return val < 5; }
这一点可以从IL层面看出。使用Reflector进行反编译:
private static void Main(string[] args){
List<int> <>g__initLocal0 = new List<int>(); <>g__initLocal0.Add(2); <>g__initLocal0.Add(3); <>g__initLocal0.Add(4); <>g__initLocal0.Add(5); <>g__initLocal0.Add(6); <>g__initLocal0.Add(7); <>g__initLocal0.Add(8); <>g__initLocal0.Add(9); <>g__initLocal0.Add(10); <>g__initLocal0.Add(11); IEnumerable<int> source = <>g__initLocal0; IEnumerable<int> result = GetNumbers(source, (CS$<>9__CachedAnonymousMethodDelegate2 != null) ? CS$<>9__CachedAnonymousMethodDelegate2 : (CS$<>9__CachedAnonymousMethodDelegate2 = new MyCalculateDelegate(Program.<Main>b__1))); foreach (int n in result) { Console.WriteLine(n); }}
以上,由于n => n > 5符合委托MyCalculateDelegate的定义,在内部创建了一个MyCalculateDelegate类型的委托,然后把一个编译器生成的方法<Main>b__1赋给了委托变量。
[CompilerGenerated] private static bool <Main>b__1(int n){
return (n < 5);}
<Main>b__1方法是由编译器帮我们自动生成的。
总结:lambda表达式其实是"语法糖",源代码被编译的时候,编译器会自动帮我们生成一个符合委托定义的方法,然后把该方法赋给委托。
“委托、Lambda表达式、事件系列”包括:
委托、Lambda表达式、事件系列01,委托是什么,委托的基本用法,委托的Method和Target属性
委托、Lambda表达式、事件系列02,什么时候该用委托
委托、Lambda表达式、事件系列03,从委托到Lamda表达式
委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托, 调用委托链方法,委托链异常处理
委托、Lambda表达式、事件系列05,Action委托与闭包
委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别
委托、Lambda表达式、事件系列07,使用EventHandler委托
委托、Lambda表达式、事件系列03,从委托到Lamda表达式的更多相关文章
- 委托、Lambda表达式、事件系列05,Action委托与闭包
来看使用Action委托的一个实例: static void Main(string[] args) { int i = 0; Action a = () => i++; a(); a(); C ...
- 委托、Lambda表达式、事件系列07,使用EventHandler委托
谈到事件注册,EventHandler是最常用的. EventHandler是一个委托,接收2个形参.sender是指事件的发起者,e代表事件参数. □ 使用EventHandler实现猜拳游戏 使用 ...
- 委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别
在"实现观察者模式(Observer Pattern)的2种方式"中,曾经通过接口的方式.委托与事件的方式实现过观察者模式.本篇体验使用Action实现此模式,并从中体验委托与事件 ...
- 委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托, 调用委托链方法,委托链异常处理
委托是多播委托,我们可以通过"+="把多个方法赋给委托变量,这样就形成了一个委托链.本篇的话题包括:委托链是怎样形成的,如何调用委托链方法,以及委托链异常处理. □ 调用返回类型为 ...
- 委托、Lambda表达式、事件系列02,什么时候该用委托
假设要找出整型集合中小于5的数. static void Main(string[] args) { IEnumerable<int> source = new List<int&g ...
- 委托、Lambda表达式、事件系列01,委托是什么,委托的基本用法,委托的Method和Target属性
委托是一个类. namespace ConsoleApplication1 { internal delegate void MyDelegate(int val); class Program { ...
- Lamda表达式的参数捕获,太酷了
lamda表达式有了参数捕获这个功能,让Action这个委托变得无所不能.Action委托就是无参数,无返回值的一个代理类型. 它只能对应于下面这种类型的函数声明. public void Funct ...
- 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】
1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...
- C# Note2:委托(delegate) & Lambda表达式 & 事件(event)
前言 本文主要讲述委托和Lambda表达式的基础知识,以及如何通过Lambda表达式实现委托调用,并阐述.NET如何将委托用作实现事件的方式. 参考:C#高级编程 1.什么是委托(delegate)? ...
随机推荐
- mac 安装gevent报错
运行pip install gevent报错 错误信息如下 xcrun: error: invalid active developer path (/Library/Developer/Comman ...
- 006_mac osx 应用跨屏幕
一般情况下 mac osx 中一个应用程序只能在一个屏幕上显示,作为从 windows 转过来的用户有点不太习惯,Goolge 后发现还是有解决方案的(虽然不是很好用). 打开 Mac 的系统偏好设置 ...
- Java基础84 javaBean规范
1.javaBean的概述 1.javaBeam(咖啡豆)是一种开发规范,也可以说是一种技术. 2.JavaBean就是一个普通java类,只要符合以下规定才能称作为javaBean: ...
- java 缺憾:异常的丢失
一.java的异常实现也是又缺陷的,异常作为程序出错的标志决不能被忽略,但它还是可能被轻易地忽略.下了可以看到前一个异常还没处理就抛出下一个异常,没有catch捕获异常,它被finally抛出下一个异 ...
- jTessBoxEditor工具进行Tesseract3.02.02样本训练
1.背景 前文已经简要介绍tesseract ocr引擎的安装及基本使用,其中提到使用-l eng参数来限定语言库,可以提高识别准确率及识别效率. 本文将针对某个网站的验证码进行样本训练,形成自己的语 ...
- 原 nc在centos7上的安装和简单使用
https://blog.csdn.net/qq_16414307/article/details/50291341 https://www.cnblogs.com/rocky-AGE-24/p/69 ...
- GitLab备份的创建与恢复
使用Gitlab一键安装包安装Gitlab非常简单, 同样的备份恢复与迁移也非常简单. 使用一条命令即可创建完整的Gitlab备份: gitlab-rake gitlab:backup:create使 ...
- winform解析json
在使用C#开发爬虫程序时,会遇到需要解析json字符串的情况.对于json字符串可以使用正则表达式的形式进行解析,更为方便的方法是使用Newtonsoft.Json来实现. Nuget添加应用包 在工 ...
- 002 @RequestMapping的说明
一:修饰方法 1.举例 2.效果 二:修饰类 1.测试类 2.index.jsp 3.效果 ---------------- 三:映射请求请求方法 1.使用语法 分别是method 2.Method的 ...
- [java] DOS编译 .java 文件得到 .class 文件 并执行 以及使用外部 .jar包 时的命令
当写一个java文件后,在DOS中进行编译与执行时,如果没有引入外来的包,那情况很简单 例如: public class hello_world { public static void main(S ...