2010-11-24 83 views
0

下面的程序为什么事件在这种情况下表现不同?

static IEnumerable<Action> Create() 
{ 
    foreach (var i in Enumerable.Range(0, 2)) 
    { 
     yield return() => { Console.Write(i); }; 
    } 
} 

static void Main(string[] args) 
{ 
    foreach (var func in Create()) 
    { 
     func(); 
    } 

    Console.ReadLine(); 
} 

OUPUTS

,并将该软件

static event Action SomethingHappened; 

static void Register() 
{ 
    foreach (var i in Enumerable.Range(0, 2)) 
    { 
     SomethingHappened +=() => { Console.Write(i); }; 
    } 
} 

static void Main(string[] args) 
{ 
    Register(); 
    SomethingHappened(); 
    Console.ReadLine(); 
} 

输出

这是为什么?如何使程序2输出01

回答

3

您正在捕获您的lambda表达式中的循环变量。这意味着,当最终被调用的委托,它将使用变量...这将永远是最新的值1试试这个:

foreach (var i in Enumerable.Range(0, 2)) 
{ 
    int copy = i; 
    SomethingHappened +=() => { Console.Write(copy); }; 
} 

...然后读Eric Lippert's blog post一下吧。

1

在第二个程序中,变量i被lambda捕获。为了获得正确的行为,在使用lambda之前先制作本地副本。例如。

foreach (var i in Enumerable.Range(0, 2)) 
{ 
    var local = i; 
    SomethingHappened +=() => { Console.Write(local); }; 
} 
相关问题