出处:http://www.cnblogs.com/birdwudi/archive/2010/08/20/1804342.html

------------------------------------------------------------------------------

简单来讲,闭包允许你将一些行为封装,将它像一个对象一样传来递去,而且它依然能够访问到原来第一次声明时的上下文

奇怪的局部变量:讨论一下C#中的闭包

[]静态全局字段

C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication3
{
class Program
{
public static int copy;//[0]这个不是闭包
static void Main()
{
//定义动作组
List<Action> actions = new List<Action>();
for (int counter = ; counter < ; counter++)
{
copy = counter;
actions.Add(() => Console.WriteLine(copy));
}
//执行动作
foreach (Action action in actions) action();
}
}
} //注:Action定义如下:
//public delegate void Action(); []局部变量(闭包一) C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication3
{
class Program
{
static void Main()
{
int copy;//[1]闭包一
//定义动作组
List<Action> actions = new List<Action>();
for (int counter = ; counter < ; counter++)
{
copy = counter;
actions.Add(() => Console.WriteLine(copy));
}
//执行动作
foreach (Action action in actions) action();
}
}
} //注:Action定义如下:
//public delegate void Action(); []局部变量(闭包二) C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication3
{
class Program
{
static void Main()
{
//定义动作组
List<Action> actions = new List<Action>();
for (int counter = ; counter < ; counter++)
{
int copy;//[1]闭包二
copy = counter;
//int copy = counter;//换种写法
actions.Add(() => Console.WriteLine(copy));
}
//执行动作
foreach (Action action in actions) action();
}
}
} //注:Action定义如下:
//public delegate void Action(); []局部变量(闭包三) C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication3
{
class Program
{
static void Main()
{
//定义动作组
List<Action> actions = new List<Action>();
for (int counter = ; counter < ; counter++)//[3]闭包三
{
actions.Add(() => Console.WriteLine(counter));
}
//执行动作
foreach (Action action in actions) action();
}
}
} //注:Action定义如下:
//public delegate void Action(); []:输出什么?
[]:输出什么?
[]:输出什么?
[]:输出什么? 这几个例子,可以将匿名函数进行转换,这样可以看的更清楚
在[]中,“外部变量”copy是类的一个静态成员,因此可以讲匿名函数转换为以下形式: C# code class Program
{
public static int copy;//[0]这个不是闭包
static void TempMethod()
{
Console.WriteLine(copy);
}
static void Main()
{
//定义动作组
List<Action> actions = new List<Action>();
for (int counter = ; counter < ; counter++)
{
copy = counter;
actions.Add(new Action(TempMethod));
}
//执行动作
foreach (Action action in actions) action();
}
} [],[]中“外部变量”copy是Main方法中的局部变量,局部变量的生存期现在必须至少延长为匿名函数委托的生存期。这可以通过将局部变量“提升”到编译器生成的类的字段来实现。之后,局部变量的实例化对应于为编译器生成的类创建实例,而访问局部变量则对应于访问编译器生成的类的实例中的字段。而且,匿名函数将会成为编译器生成类的实例方法: C# code class Program
{
static void Main()
{
//定义动作组
TempClass tc = new TempClass();
//定义动作组
List<Action> actions = new List<Action>();
for (int counter = ; counter < ; counter++)
{
tc.copy = counter;
actions.Add(tc.TempMethod);
}
//执行动作
foreach (Action action in actions) action();
}
class TempClass
{
public int copy;
public void TempMethod()
{
Console.WriteLine(copy);
}
}
} C# code class Program
{
static void Main()
{
//定义动作组 //定义动作组
List<Action> actions = new List<Action>();
for (int counter = ; counter < ; counter++)
{
TempClass tc = new TempClass();
tc.copy = counter;
actions.Add(tc.TempMethod);
}
//执行动作
foreach (Action action in actions) action();
}
class TempClass
{
public int copy;
public void TempMethod()
{
Console.WriteLine(copy);
}
}
} []中的“外部变量”counter是for循环的循环因子,因此可以转换为以下形式: C# code class Program
{
static void Main()
{
//定义动作组
List<Action> actions = new List<Action>();
TempClass tc = new TempClass();
for (tc.copy = ; tc.copy < ; tc.copy++)
{
actions.Add(new Action(tc.TempMethod));
}
//执行动作
foreach (Action action in actions) action();
}
class TempClass
{
public int copy;
public void TempMethod()
{
Console.WriteLine(copy);
}
}
}

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. Modelica学习

    Annotation Choices for Suggested Redeclarations and Modifications Replaceable model sample(start,int ...

  2. 关于C#程序无故退出

    今天我发现一种情况,分享下 我一个对象是用多线程写的代码,主程序调用完后有时候也会退出,catch不到.我在原对象的接口里面加上lock之后就ok了!我的理解是该对象申请的资源没释放完毕,加lock后 ...

  3. Net 分页功能的实现

    首先写一个接口   1 2 3 4 5 6 public interface IPagedList     {         int CurrentPageIndex { get; set; }   ...

  4. JS中简单原型的使用

  5. C#,java,C++ 等变量命名规则

    命名规则: 必须以“字母” .“_”或“@”开头,不要以数字开头. 后面可以跟任意“数字”,“字母”,“下划线”. ---注意:自己起的名字尽量避免与系统中的关键字重复.不推荐重新定义相同的变量名. ...

  6. zabbix3.0安装部署文档

    zabbix v3.0安装部署 摘要: 本文的安装过程摘自http://www.ttlsa.com/以及http://b.lifec-inc.com ,和站长凉白开的<ZABBIX从入门到精通v ...

  7. scala 学习之: list.fill 用法

    题目描述: Decode a run-length encoded list. Given a run-length code list generated as specified in probl ...

  8. Quickly place a window to another screen using only the keyboard

    http://askubuntu.com/questions/22207/quickly-place-a-window-to-another-screen-using-only-the-keyboar ...

  9. Google统计

    <!-- Google Analytics --><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i ...

  10. iOS中坐标转换

    坐标转换,可以用UIVIew的方法 //由要转换坐标view的superView执行该方法,rect为待转换view的frame,view是要显示到哪儿的 - (CGRect)convertRect: ...