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 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
随机推荐
- mysql修改数据库的存储引擎(InnoDB)
查看当前的存储引擎 show engines; 基本的差别:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不 ...
- springboot 集成swagger2
使用Swagger 可以动态生成Api接口文档,在项目开发过程中可以帮助前端开发同事减少和后端同事的沟通成本,而是直接参照生成的API接口文档进行开发,提高了开发效率.这里以springboot(版本 ...
- 树上数据结构——LCT
目录 树上数据结构--LCT 概述 基本概念 核心操作 其他操作 完整模板 树上数据结构--LCT 概述 LCT是一种强力的树上数据结构,支持以下操作: 链上求和 链上求最值 链上修改 子树修改 子树 ...
- ArcGIS Server10.1 动态图层服务
动态图层的应用场景: 1 改变现有图层:符号,渲染方式和版本,这些都可以通过客户端请求的时候给定相应的参数来进行设置,从而来达到轻易改变地图的效果. 2 添加地图服务中没有的图层 添加的数据可以是矢量 ...
- Mysql高手系列 - 第18篇:mysql流程控制语句详解(高手进阶)
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 这是Mysql系列第18篇. 环境:mysql5.7.25,cmd命令中进行演示. 代码中被[]包含的表示可选,|符 ...
- PHP--网络协议相关知识
HTTP状态码 HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码. HTTP状态码主要有5种,代表5种不同类型的响应: 1xx:信息性状态码,代表接 ...
- 面试官:你有m个鸡蛋,如何用最少的次数测出鸡蛋会在哪一层碎?
假设你面前有一栋n层的大楼和m个鸡蛋,假设将鸡蛋从f层或更高的地方放扔下去,鸡蛋才会碎,否则就不会.你需要设计一种策略来确定f的值,求最坏情况下扔鸡蛋次数的最小值. leetcode原题链接 乍一看这 ...
- Vue中使用key的作用
key的作用是为了在diff算法执行时更快的找到对应的节点,提高diff速度 key具有唯一性 vue中循环需加 :key=“唯一标识” ,唯一标识可以使item里面id index 等,因为vue组 ...
- 可能是国内第一篇全面解读 Java 现状及趋势的文章
作者 | 张晓楠 Dragonwell JDK 最新版本 8.1.1-GA 发布,包括全新特性和更新! 导读:InfoQ 发布<2019 中国 Java 发展趋势报告>,反映 Java 在 ...
- 索引的底层实现(B 树)
一.B 树 1.B-Tree介绍 B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点:重复,直到所对应的儿子指针为空,或已经是叶 ...