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 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
随机推荐
- C++基础之动态内存
C++支持动态分配对象,它的生命周期与它们在哪里创建无关,只有当显示的被释放时,这些对象才会被销毁.分配在静态或栈内存中的对象由编译器自动创建和销毁. new在动态内存中为对象分配空间并返回一个指向该 ...
- js禁止刷新的简单方法
//禁止用F5键 这个是键盘按下时触发document.onkeydown = function() { if ( event.keyCode==116) {event.keyCode = 0; e ...
- Java 提取Word中的文本和图片
本文将介绍通过Java来提取或读取Word文档中文本和图片的方法.这里提取文本和图片包括同时提取文档正文当中以及页眉.页脚中的的文本和图片. 使用工具:Free Spire.Doc for Java ...
- Spring框架学习笔记(3)——SpringMVC框架
SpringMVC框架是基于Spring框架,可以让我们更为方便的进行Web的开发,实现前后端分离 思路和原理 我们之前仿照SpringMVC定义了一个自定义MVC框架,两者的思路其实都是一样的. 建 ...
- html实现打印预览效果
前面说到利用lodop插件进行打印设置,那个应用于打印快递面单,或者跟快递面单相似场景的情况. 今天的利用html快速打印出A4纸大小的场景,例如:合同.静态文本等. 效果如下: 方式一 1.设置di ...
- WebGL简易教程(六):第一个三维示例(使用模型视图投影变换)
目录 1. 概述 2. 示例:绘制多个三角形 2.1. Triangle_MVPMatrix.html 2.2. Triangle_MVPMatrix.js 2.2.1. 数据加入Z值 2.2.2. ...
- Python爬虫(三):BeautifulSoup库
BeautifulSoup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库,它能够将 HTML 或 XML 转化为可定位的树形结构,并提供了导航.查找.修改功能,它会自动将输入 ...
- ThinkPHP5 支付宝 电脑与手机支付扩展库
ThinkPHP5 电脑与手机支付扩展库(2017年9月18日) 使用说明 在默认配置情况下,将文件夹拷贝到根目录即可, 其中extend目录为支付扩展目录, application\extra\al ...
- HBase学习与实践
Photo by bealach verse on Unsplash 参考书籍:<HBase 权威指南> -- Lars George著. 文章为个人从零开始学习记录,如有错误,还请不吝赐 ...
- linux分析工具之vmstat详解
一.概述 vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况.首先我们查看下帮助.如下图所 ...