C# 闭包对像
主要内容:
1、描述出现的现像
2、分析其出现的原因
3、提示
一、看如下一段代码及结果
class Program
{
static void Main(string[] args)
{
List<Action> lists = new List<Action>();
for (int i = ; i < ; i++)
{ Action t = () =>
{ Console.WriteLine(i.ToString());
};
lists.Add(t);
}
foreach (var t in lists)
{
t();
} Console.Read();
}
}
class Program
{
static void Main(string[] args)
{
List<Action> lists = new List<Action>();
for (int i = ; i < ; i++)
{
int temp = i;
Action t = () =>
{
Console.WriteLine(temp.ToString()); };
lists.Add(t);
}
foreach (var t in lists)
{
t();
} Console.Read();
}
}
为什么加了一个临时变量就结果不一样了呢?
二、现像分析
我们查看第一段代码的il和第二段的il
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代码大小 149 (0x95)
.maxstack
.locals init ([] class [mscorlib]System.Collections.Generic.List`<class [mscorlib]System.Action> lists,
[] class [mscorlib]System.Action t,
[] class [mscorlib]System.Action 'CS$<>9__CachedAnonymousMethodDelegate1',
[] class iltest.Program/'<>c__DisplayClass2' 'CS$<>8__locals3',
[] bool CS$$,
[] valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<class [mscorlib]System.Action> CS$$)
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`<class [mscorlib]System.Action>::.ctor()
IL_0006: stloc.
IL_0007: ldnull
IL_0008: stloc.
IL_0009: newobj instance void iltest.Program/'<>c__DisplayClass2'::.ctor()
IL_000e: stloc.
IL_000f: ldloc.
IL_0010: ldc.i4.
IL_0011: stfld int32 iltest.Program/'<>c__DisplayClass2'::i
IL_0016: br.s IL_0044
IL_0018: nop
IL_0019: ldloc.
IL_001a: brtrue.s IL_002b
IL_001c: ldloc.
IL_001d: ldftn instance void iltest.Program/'<>c__DisplayClass2'::'<Main>b__0'()
IL_0023: newobj instance void [mscorlib]System.Action::.ctor(object,
native int)
IL_0028: stloc.
IL_0029: br.s IL_002b
IL_002b: ldloc.
IL_002c: stloc.
IL_002d: ldloc.
IL_002e: ldloc.
IL_002f: callvirt instance void class [mscorlib]System.Collections.Generic.List`<class [mscorlib]System.Action>::Add(!)
IL_0034: nop
IL_0035: nop
IL_0036: ldloc.
IL_0037: dup
IL_0038: ldfld int32 iltest.Program/'<>c__DisplayClass2'::i
IL_003d: ldc.i4.
IL_003e: add
IL_003f: stfld int32 iltest.Program/'<>c__DisplayClass2'::i
IL_0044: ldloc.
IL_0045: ldfld int32 iltest.Program/'<>c__DisplayClass2'::i
IL_004a: ldc.i4.
IL_004b: clt
IL_004d: stloc.s CS$$
IL_004f: ldloc.s CS$$
IL_0051: brtrue.s IL_0018
IL_0053: nop
IL_0054: ldloc.
IL_0055: callvirt instance valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<!> class [mscorlib]System.Collections.Generic.List`<class [mscorlib]System.Action>::GetEnumerator()
IL_005a: stloc.s CS$$
.try
{
IL_005c: br.s IL_006f
IL_005e: ldloca.s CS$$
IL_0060: call instance ! valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<class [mscorlib]System.Action>::get_Current()
IL_0065: stloc.
IL_0066: nop
IL_0067: ldloc.
IL_0068: callvirt instance void [mscorlib]System.Action::Invoke()
IL_006d: nop
IL_006e: nop
IL_006f: ldloca.s CS$$
IL_0071: call instance bool valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<class [mscorlib]System.Action>::MoveNext()
IL_0076: stloc.s CS$$
IL_0078: ldloc.s CS$$
IL_007a: brtrue.s IL_005e
IL_007c: leave.s IL_008d
} // end .try
finally
{
IL_007e: ldloca.s CS$$
IL_0080: constrained. valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<class [mscorlib]System.Action>
IL_0086: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_008b: nop
IL_008c: endfinally
} // end handler
IL_008d: nop
IL_008e: call int32 [mscorlib]System.Console::Read()
IL_0093: pop
IL_0094: ret
} // end of method Program::Main
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代码大小 127 (0x7f)
.maxstack
.locals init ([] class [mscorlib]System.Collections.Generic.List`<class [mscorlib]System.Action> lists,
[] int32 i,
[] class [mscorlib]System.Action t,
[] class iltest.Program/'<>c__DisplayClass1' 'CS$<>8__locals2',
[] bool CS$$,
[] valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<class [mscorlib]System.Action> CS$$)
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`<class [mscorlib]System.Action>::.ctor()
IL_0006: stloc.
IL_0007: ldc.i4.
IL_0008: stloc.
IL_0009: br.s IL_0033
IL_000b: newobj instance void iltest.Program/'<>c__DisplayClass1'::.ctor()
IL_0010: stloc.
IL_0011: nop
IL_0012: ldloc.
IL_0013: ldloc.
IL_0014: stfld int32 iltest.Program/'<>c__DisplayClass1'::temp
IL_0019: ldloc.
IL_001a: ldftn instance void iltest.Program/'<>c__DisplayClass1'::'<Main>b__0'()
IL_0020: newobj instance void [mscorlib]System.Action::.ctor(object,
native int)
IL_0025: stloc.
IL_0026: ldloc.
IL_0027: ldloc.
IL_0028: callvirt instance void class [mscorlib]System.Collections.Generic.List`<class [mscorlib]System.Action>::Add(!)
IL_002d: nop
IL_002e: nop
IL_002f: ldloc.
IL_0030: ldc.i4.
IL_0031: add
IL_0032: stloc.
IL_0033: ldloc.
IL_0034: ldc.i4.
IL_0035: clt
IL_0037: stloc.s CS$$
IL_0039: ldloc.s CS$$
IL_003b: brtrue.s IL_000b
IL_003d: nop
IL_003e: ldloc.
IL_003f: callvirt instance valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<!> class [mscorlib]System.Collections.Generic.List`<class [mscorlib]System.Action>::GetEnumerator()
IL_0044: stloc.s CS$$
.try
{
IL_0046: br.s IL_0059
IL_0048: ldloca.s CS$$
IL_004a: call instance ! valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<class [mscorlib]System.Action>::get_Current()
IL_004f: stloc.
IL_0050: nop
IL_0051: ldloc.
IL_0052: callvirt instance void [mscorlib]System.Action::Invoke()
IL_0057: nop
IL_0058: nop
IL_0059: ldloca.s CS$$
IL_005b: call instance bool valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<class [mscorlib]System.Action>::MoveNext()
IL_0060: stloc.s CS$$
IL_0062: ldloc.s CS$$
IL_0064: brtrue.s IL_0048
IL_0066: leave.s IL_0077
} // end .try
finally
{
IL_0068: ldloca.s CS$$
IL_006a: constrained. valuetype [mscorlib]System.Collections.Generic.List`/Enumerator<class [mscorlib]System.Action>
IL_0070: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0075: nop
IL_0076: endfinally
} // end handler
IL_0077: nop
IL_0078: call int32 [mscorlib]System.Console::Read()
IL_007d: pop
IL_007e: ret
} // end of method Program::Main
class Program
{
static void Main(string[] args)
{
List<Action> lists = new List<Action>();
TempClass tc = new TempClass(); for ( tc.i = ; tc.i < ; tc.i++)
{
Action t = tc.FuncWrite;
lists.Add(t);
}
foreach (var t in lists)
{
t();
} Console.Read();
}
}
class TempClass
{
public int i;
public void FuncWrite()
{
Console.WriteLine(i.ToString());
} }
说一个查看il 进入命令行,ildasm
理论分析以后补上。
C# 闭包对像的更多相关文章
- 《Web 前端面试指南》1、JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- 干货分享:让你分分钟学会 JS 闭包
闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述 ...
- 深入浅出JavaScript之闭包(Closure)
闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...
- javascript之闭包理解以及应用场景
半个月没写博文了,最近一直在弄小程序,感觉也没啥好写的. 之前读了js权威指南,也写了篇博文,但是实话实说当初看闭包确实还是一头雾水.现在时隔一个多月(当然这一段时间还是一直有在看闭包的相关知识)理解 ...
- js闭包 和 prototype
function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...
- js闭包for循环总是只执行最后一个值得解决方法
<style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...
- JavaScript学习笔记(二)——闭包、IIFE、apply、函数与对象
一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...
- 带你一分钟理解闭包--js面向对象编程
上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...
- 如何设计一门语言(七)——闭包、lambda和interface
人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...
- JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
随机推荐
- 三段式有限状态机Verilog代码
状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作.完成特定操作的控制中心.有限状态机简写为FSM(Finite State Machine),主 ...
- java数据结构——队列、循环队列(Queue)
每天进步一点点,坚持就是成功. 1.队列 /** * 人无完人,如有bug,还请斧正 * 继续学习Java数据结构————队列(列队) * 队列和栈一样,都是使用数组,但是队列多了一个队头,队头访问数 ...
- 多智能体系统(MAS)简介
1.背景 自然界中大量个体聚集时往往能够形成协调.有序,甚至令人感到震撼的运动场景,比如天空中集体翱翔的庞大的鸟群.海洋中成群游动的鱼群,陆地上合作捕猎的狼群.这些群体现象所表现出的分布.协调.自 ...
- 基于操作系统原理的Linux 系统的安装
一.实验目的 1.了解Linux操作系统的发行版本. 2.掌握Red Hat Linux 9.0的安装方法. (可用Red Hat Linux 5.0版本替代9.0版本) 3.了解Linux其他版本( ...
- 【Django】一对多表结构
1.创建project数据库表 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.co ...
- Redis连接池-Java代码
1.JedisUtil类 2.测试类 3.测试日志(模拟出现竞争情况) import org.apache.log4j.Logger; import redis.clients.jedis.Jedis ...
- linux 安装docker
1.安装环境 此处在Centos7进行安装,可以使用以下命令查看CentOS版本 lsb_release -a 在 CentOS 7安装docker要求系统为64位.系统内核版本为 3.10 以上,可 ...
- CSS 换行
默认情况下,元素的属性是 white-space:normal:自动换行:(不把单词截断,会把单词看作一个整体) -----但是但是但是但是..当元素中的内容是一对没有空格的字符/数字时,超过容器宽度 ...
- <<Java并发编程的艺术>>-阅读笔记和思维导图
最近在坚持每天阅读<>,不但做好笔记(MarkDown格式),还做好思维导图. 如果大家感兴趣,可以可以到码云上阅读笔记和到ProcessOn上阅读思维导图. 码云:https://git ...
- JDK-基于Windows环境搭建
JDK安装: 毋庸置疑你要跑java程序,肯定少不了JDK,如jemter还有还有~ 下载jdk地址1:https://pan.baidu.com/s/1FIvGNvZSy0EpCBxHCz07nA ...