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

时间:2010-11-24 12:32:29

标签: c# events delegates ienumerable

以下计划

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

  

01

这个程序

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();
}

输出

  

11

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

2 个答案:

答案 0 :(得分:3)

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

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

...然后阅读Eric Lippert's blog post

答案 1 :(得分:1)

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

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