委托、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)? ...
随机推荐
- Google Protocol Buffer的安装与.proto文件的定义(转)
转自(https://www.cnblogs.com/yinheyi/p/6080244.html) 什么是protocol Buffer呢? Google Protocol Buffer( 简称 P ...
- 安装Scrapy遇到的坑
安装过程怕是要吐血,架梯子等等结果被setuptools的版本给坑了. 参考网址: http://blog.csdn.net/YHYR_YCY/article/details/78876148 htt ...
- Python_oldboy_自动化运维之路_socket编程(十)
链接:http://www.cnblogs.com/linhaifeng/articles/6129246.html 1.osi七层 引子: 须知一个完整的计算机系统是由硬件.操作系统.应用软件三者组 ...
- supervisor安装部署和使用实例
Supervisord是用Python实现的一款非常实用的进程管理工具,类似于monit,monit和supervisord的一个比较大的差异是supervisord管理的进程必须由superviso ...
- 移动端经常出现的兼容问题,谈谈移动端应用或者wap站的一些优化技巧和心得
移动端经常出现的兼容问题,谈谈移动端应用或者wap站的一些优化技巧和心得 1. 安卓浏览器看背景图片,有些设备会模糊. 因为手机分辨率太小,如果按照分辨率来显示网页,字会非常小,安卓手机 ...
- 【PAT】1103 Integer Factorization(30 分)
The K−P factorization of a positive integer N is to write N as the sum of the P-th power of K positi ...
- 【BZOJ】2120: 数颜色
题解 练习一下带修改莫队 先按照左端点的块排序,再按照右端点的块排序,然后按照时间排序 每个修改操作存一下修改前这个位置的值就可以逆序操作了 代码 #include <bits/stdc++.h ...
- 如何快速的打开当前文件夹的dos命令窗口
一.常规方法: 1.使用 “window + R” 组合键,输入cmd回车.如下图所示: 2.如果你要定位到指定的文件夹,那么需要用cd等命令来处理.如下图所示: 二.快速方法: 按住“shift”键 ...
- 查看浏览器中Cookie信息
一般在浏览器的设置中能找到Cookie的相关设置和查看信息 在js中使用 alert(document.cookie) 也能查看到当前页面的 Cookie 信息实现方式1.若是自己开发的页面 直接在j ...
- 黑苹果 之 神舟战神Z7M-SL7D2
黑苹果引导工具 Clover 配置详解:http://www.jianshu.com/p/b156b0177a24 神舟Z7m UEFI+GPT安装WIN10+MAC OS X Yosemite双系统 ...