C# 闭包

转自

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


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

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

[0]静态全局字段

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 = 0 ; counter < 10 ; counter ++ ) { copy = counter; actions.Add(() => Console.WriteLine(copy)); } // 执行动作 foreach (Action action in actions) action(); } } } // 注:Action定义如下: // public delegate void Action();



[1]局部变量(闭包一)

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 = 0 ; counter < 10 ; counter ++ ) { copy = counter; actions.Add(() => Console.WriteLine(copy)); } // 执行动作 foreach (Action action in actions) action(); } } } // 注:Action定义如下: // public delegate void Action();



[2]局部变量(闭包二)

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 = 0 ; counter < 10 ; 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();



[3]局部变量(闭包三)

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 = 0 ; counter < 10 ; counter ++ ) // [3]闭包三 { actions.Add(() => Console.WriteLine(counter)); } // 执行动作 foreach (Action action in actions) action(); } } } // 注:Action定义如下: // public delegate void Action();



[0]:输出什么?
[1]:输出什么?
[2]:输出什么?
[3]:输出什么?

 

 

这几个例子,可以将匿名函数进行转换,这样可以看的更清楚
在[0]中,“外部变量”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 = 0 ; counter < 10 ; counter ++ ) { copy = counter; actions.Add( new Action(TempMethod)); } // 执行动作 foreach (Action action in actions) action(); } }



[1],[2]中“外部变量”copy是Main方法中的局部变量,局部变量的生存期现在必须至少延长为匿名函数委托的生存期。这可以通过将局部变量“提升”到编译器生成的类的字段来实现。之后,局部变量的实例化对应于为编译器生成的类创建实例,而访问局部变量则对应于访问编译器生成的类的实例中的字段。而且,匿名函数将会成为编译器生成类的实例方法:

C# code
    
    
    
    
class Program { static void Main() { // 定义动作组 TempClass tc = new TempClass(); // 定义动作组 List < Action > actions = new List < Action > (); for ( int counter = 0 ; counter < 10 ; 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 = 0 ; counter < 10 ; 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); } } }



[3]中的“外部变量”counter是for循环的循环因子,因此可以转换为以下形式:

C# code
    
    
    
    
class Program { static void Main() { // 定义动作组 List < Action > actions = new List < Action > (); TempClass tc = new TempClass(); for (tc.copy = 0 ; tc.copy < 10 ; 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# 闭包)