开发者

Why events behave differently in this case?

开发者 https://www.devze.com 2023-01-26 12:45 出处:网络
The following program static IEnumerable<Action> Create() { foreach (var i in Enumerable.Range(0, 2))

The following program

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

static vo开发者_如何学运维id Main(string[] args)
{
    foreach (var func in Create())
    {
        func();
    }

    Console.ReadLine();
}

ouputs

01

And this program

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

outputs

11

Why is that so? How to make the program 2 output 01?


You're capturing the loop variable in your lambda expression. That means when the delegate is finally invoked, it will use the latest value of the variable... which will always be 1. Try this:

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

... then read Eric Lippert's blog post about it.


In the second program the variable i is captured by the lambda. To get the correct behavior make a local copy before using it in the lambda. E.g.

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

精彩评论

暂无评论...
验证码 换一张
取 消