主要内容:

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# 闭包对像的更多相关文章

  1. 《Web 前端面试指南》1、JavaScript 闭包深入浅出

    闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...

  2. 干货分享:让你分分钟学会 JS 闭包

    闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述 ...

  3. 深入浅出JavaScript之闭包(Closure)

    闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...

  4. javascript之闭包理解以及应用场景

    半个月没写博文了,最近一直在弄小程序,感觉也没啥好写的. 之前读了js权威指南,也写了篇博文,但是实话实说当初看闭包确实还是一头雾水.现在时隔一个多月(当然这一段时间还是一直有在看闭包的相关知识)理解 ...

  5. js闭包 和 prototype

    function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...

  6. js闭包for循环总是只执行最后一个值得解决方法

    <style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...

  7. JavaScript学习笔记(二)——闭包、IIFE、apply、函数与对象

    一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...

  8. 带你一分钟理解闭包--js面向对象编程

    上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...

  9. 如何设计一门语言(七)——闭包、lambda和interface

    人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...

  10. JavaScript 闭包深入浅出

    闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...

随机推荐

  1. SpringBoot和Hibernate整合

    1.先使用idea创建maven项目(这个就不详细讲了,很简单的操作) 2.创建完maven项目之后添加springboot依赖,pom.xml文件如下: <?xml version=" ...

  2. [Advanced Python] 10 - Transfer parameters

    动态库调用 一.Python调用 .so From: Python调用Linux下的动态库(.so) (1) 生成.so:.c to .so lolo@-id:workme$ gcc -Wall -g ...

  3. iOS 开发中一些 tips

    tableView 的 tableHeaderView 高度不正确的问题: func forceRefreshHeader() { let size = headerView.systemLayout ...

  4. 使用Git工具批量拉取代码

    公司项目比较多,每天上班第一件事就是拉取代码,cd A 目录 git pull cd .. cd B ...... 一个项目一个项目的拉取,感觉也是很费劲的,那么有没有什么一键操作呢 现在执行一个命令 ...

  5. FlagCounter被封杀?自己实现一个简单的多国访客计数器

    起因 前段时间发现博客右边的FlagCounter计数器突然没了,又看到了博客园封杀了FlagCounter的消息,有点摸不着头脑.于是上FlagCounter的网站上看了一眼,发现最近出现的来自新国 ...

  6. Jetpack系列:LiveData入门级使用方法

    Android APP开发中,开发者们都想有一个公共的组件,可以实现后台数据的监听,同时实时更新到UI进行显示,从而大大简化开发过程.Google针对这一开发需求,提供了Jetpack LiveDat ...

  7. Python基础(十二)

    今日主要内容 推导式 生成器表达式 lambda匿名函数 内置函数介绍 一.推导式 (一)列表推导式 先来看一段代码 建立一个空列表,向空列表中添加元素 lst = list() for i in r ...

  8. 波士顿房价预测 - 最简单入门机器学习 - Jupyter

    机器学习入门项目分享 - 波士顿房价预测 该分享源于Udacity机器学习进阶中的一个mini作业项目,用于入门非常合适,刨除了繁琐的部分,保留了最关键.基本的步骤,能够对机器学习基本流程有一个最清晰 ...

  9. C/C++ 中带空格字符串输入的一些小trick

    今天在重温 C++ 的时候发现自己存在的一些问题,特此记录下来. 我们可以看一下下面这段代码: #include <iostream> #include <cstdio> #i ...

  10. layui table异步调用数据的时候,数据展示不出来现象解决方案

    最近使用layui table进行异步获取数据并填充的时候,控制台打印出数据长度为0,但是其中还有数据,网上找了很多办法,下边是我最后使用的. 一般,render渲染表格是独立的书写格式,但是我在做数 ...