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 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
随机推荐
- [Leetcode] 第289题 生命游戏
一.题目描述 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初 ...
- uboot学习之uboot.bin的运行流程
上篇博客:http://www.cnblogs.com/yeqluofwupheng/p/7347925.html 讲到uboot-spl的工作流程,接下来简述一下uboot.bin的工作流程,这对应 ...
- 制作mysql大数据表验证覆盖索引
昨天跟同事聊起数据表性能的问题,能不能仅用覆盖索引实现数据的汇总统计.找了一个开发环境已有的数据表进行测试,通过explain命令,能看到mysql通过覆盖索引就能实现sum的需求,而无须去读取实际行 ...
- DW网页代码笔记
DW网页代码笔记 1.样式. class 插入类样式 标签技术(html)解决页面的内容样式技术(css)解决页面的外观脚本技术 解决页面动态交互问题<form> ...
- Intellij IDEA 2019 + Java Spring MVC + Hibernate学习笔记(1)
之前的技术栈一直是围绕.net 做的,现在.net 技术栈的使用越来越少,越来越窄.好多原来的同事都转Java开发了. 最近公司变动,自己需要重新找个坑,压力山大.好多要求Java技术栈的根本没机会进 ...
- Spotlight性能监控工具的配置及使用
这是我离线整理资料里的内容,大概是2012年时候开始使用此性能监控工具的,直到至今,接触到几个性能监控工具里,还是美国quest公司生产的Spotlight此产品相对比较牛! 我也不知道现在发展到能支 ...
- VirtualBox 安装摄像头驱动
1. 需下载与VM Virtualbox相匹配的驱动,因为我的虚拟机版本是5.2.8,所以就下载5.2版本的驱动: https://www.virtualbox.org/wiki/Download_O ...
- 3D漫游的分类 3D Navigation Taxonomy
在2001年CHI发表的论文中1,Tan等人提出了一种对3D漫游的分类方法. 当时关于3D漫游(3D Navigation)的研究主要分为两种:一种是发掘有关漫游的认知原则,一种是开发一些具体的漫游技 ...
- Go语言基础之net/http
Go语言基础之net/http 2017年6月26日 Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现. net/http介绍 Go语言内置的net/http包提供了HT ...
- 关于MySQL退出命令,还有你不知道的一种操作
前两天再进MySQL窗口的时候,手快点了一个 ' ,并且按下了enter键,于是就出现了这种情况, 然后就退不出来了,为此我还特意上网查了一下,最后的结果基本上都是只能关闭MySQL 重新进入. 因为 ...