委托、Lambda表达式、事件系列05,Action委托与闭包
来看使用Action委托的一个实例:
static void Main(string[] args){int i = 0;Action a = () => i++;a();a();Console.WriteLine(i);}
结果是期望能的2。但令人好奇的是:栈上的变量i是如何传递给Action委托的?
反编译进行查看,首先看Main方法对应的IL代码:
再看c_DisplayClass1的IL代码:
从中可以看出:
→在托管堆上创建了一个名为c_DisplayClass1的实例
→把栈上变量i的值赋值给了c_DisplayClass1的实例字段i
→编译器() => i++;Lambda表达式表示的匿名委托起了个<Main>b_0的方法名,并成为了c_DisplayClass1的实例方法
→把c_DisplayClass1的实例方法<Main>b_0赋值给Action委托变量
→最后调用委托2次,这2次都是针对c_DisplayClass1的实例字段i
换句话说,在托管堆上创建了对象实例,形成"闭包"。栈上的变量变成了闭包的实例字段,Lambda表达式所表示的匿名委托变成了闭包的实例方法。
以上,创建了一个Action,形成了一个"闭包",接下来创建2个Action,形成2个"闭包",看"闭包"的实例字段是否相互影响?
static void Main(string[] args){Action a = GetAction();Action b = GetAction();Console.Write("第一次调用a,i的值=");a();Console.WriteLine();Console.Write("第二次调用a,i的值=");a();Console.WriteLine();Console.Write("第一次调用b,i的值=");b();Console.WriteLine();}static Action GetAction(){Action result = null;int i = 0;result = () => Console.Write(i++);return result;}
以上,虽然是把同一个GetAction方法分别赋值给了Action委托,但GetAction方法分别在不同的"闭包"内,当调用委托执行GetAction方法的时候,各自对闭包内的实例字段i自增1并打印,相互间不影响。
总结:每个Action都有自己的"闭包",并且"闭包"间互不影响。
“委托、Lambda表达式、事件系列”包括:
委托、Lambda表达式、事件系列01,委托是什么,委托的基本用法,委托的Method和Target属性
委托、Lambda表达式、事件系列02,什么时候该用委托
委托、Lambda表达式、事件系列03,从委托到Lamda表达式
委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托, 调用委托链方法,委托链异常处理
委托、Lambda表达式、事件系列05,Action委托与闭包
委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别
委托、Lambda表达式、事件系列07,使用EventHandler委托
委托、Lambda表达式、事件系列05,Action委托与闭包的更多相关文章
- 委托/lambda表达式/事件
委托 委托是执行安全的类,它的使用方式与类类似(即都需要定义再实例化),不同在于,类在实例化之后叫对象或类的实例,但委托在实例化后仍叫委托,委托可以把函数作为参数传递. 语法声明: delegate ...
- 委托+内置委托方法+多播委托+lambda表达式+事件
委托概念:如果我们要把方法当做参数来传递的话,就要用到委托.简单来说委托是一个类型,这个类型可以赋值一个方法的引用. 声明委托: 在C#中使用一个类分两个阶段,首选定义这个类,告诉编译器这个类由什么字 ...
- 委托、Lambda表达式、事件系列03,从委托到Lamda表达式
在"委托.Lambda表达式.事件系列02,什么时候该用委托"一文中,使用委托让代码简洁了不少. namespace ConsoleApplication2 { internal ...
- Unity C# 多态 委托 事件 匿名委托 Lambda表达式 观察者模式 .NET 框架中的委托和事件
一.多态 里氏替换原则: 任何能用基类的地方,可以用子类代替,反过来不行.子类能够在基类的基础上增加新的行为.面向对象设计的基本原则之一. 开放封闭原则: 对扩展开放,意味着有新的需求或变化时,可以对 ...
- C# Note2:委托(delegate) & Lambda表达式 & 事件(event)
前言 本文主要讲述委托和Lambda表达式的基础知识,以及如何通过Lambda表达式实现委托调用,并阐述.NET如何将委托用作实现事件的方式. 参考:C#高级编程 1.什么是委托(delegate)? ...
- (28)C#委托,匿名函数,lambda表达式,事件
一.委托 委托是一种用于封装命名和匿名方法的引用类型. 把方法当参数,传给另一个方法(这么说好理解,但实际上方法不能当参数,传入的是委托类型),委托是一种引用类型,委托里包含很多方法的引用 创建的方法 ...
- C#编程 委托 Lambda表达式和事件
委托 如果我们要把方法当做参数来传递的话,就要用到委托.简单来说委托是一个类型,这个类型可以赋值一个方法的引用. 声明委托 在C#中使用一个类分两个阶段,首选定义这个类,告诉编译器这个类由什么字段和方 ...
- 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】
1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...
- 委托 lambda表达式浅显理解
方法不能跟变量一样当参数传递,怎么办,C#定义了委托,就可以把方法当变量一样传递了,为了简单,匿名方法传递,省得再声明方法了:再简单,lambda表达式传递,比匿名方法更直观. public dele ...
随机推荐
- linux驱动---等待队列、工作队列、Tasklets【转】
转自:https://blog.csdn.net/ezimu/article/details/54851148 概述: 等待队列.工作队列.Tasklet都是linux驱动很重要的API,下面主要从用 ...
- zookeeper命令行客户端
前提条件:搭建好zookeeper服务器集群<Zookeeper深入认识>,并且集群成功开启. 执行zkServer.sh,客户端连接上服务器hadoop1. 都有哪些命令行操作呢?(见下 ...
- 少走弯路,一个老程序猿谈PHP职业发展规划
PHP是一个使用者非常多的开发语言,但在每个领域里的开发侧重点有所不同互联网方面,在稳定的基础上,更注重性能.高并发,高负载的处理. PHP职业发展规划一般有三条路线,一条技能专精发展路线.另两条,是 ...
- 自然语言处理---用隐马尔科夫模型(HMM)实现词性标注---1998年1月份人民日报语料---learn---test---evaluation---Demo---java实现
先放上一张Demo的测试图 测试的句子及每个分词的词性标注为: 目前/t 这/rzv 条/q 高速公路/n 之间/f 的/ude1 路段/n 已/d 紧急/a 封闭/v ./w 需要基础知识 HM ...
- Python3安装turtle提示错误:Command "python setup.py egg_info" failed with error code 1
Python3安装turtle提示错误:Command "python setup.py egg_info" failed with error code 1 Python3.5安 ...
- HttpRequest中常见的四种Content-Type(转)
add by zhj: Content-Type用于说明request body的编码格式的,对于没有request body的http method如GET,HEAD没有必要设置这个参数,当然,你设 ...
- 高能天气——团队Scrum冲刺阶段-Day 3
高能天气--团队Scrum冲刺阶段-Day 3 今日完成任务 于欣月:完成天气预报部分收尾工作 余坤澎:进行特别关心的实现 康皓越:实现闹钟部分添加音乐 范雯琪:初步开始界面优化,寻找天气预报部分的背 ...
- CSS3利用一个div实现内圆角边框效果
*首先要清楚的是,box-shadow的形状会随着border-radius变化.下面的例子可以证明: <!doctype html> <html lang="en&quo ...
- 隧道接口工具airtun-ng
隧道接口工具airtun-ng airtun-ng是aircrack-ng套件提供的一个工具.该工具可以为无线网卡建立隧道接口.通过该接口,渗透测试人员可以建立wIDS,分析指定的AP的数据.借助 ...
- 某题目2 状压DP
Description 对于一个数列,其混乱度定义为连续相等的数的段数.如:1 2 1 2 1,其混乱度为5,而:1 2 2 3 3,其混乱度为3.现给出一个数列,允许取出k个数并允许插入数列中的任意 ...