7

这可以在for循环中完成吗?

        TickEventArgs targs1 = new TickEventArgs(lbl1_up_time, _elapsedTime_up1);
        timer_up1.Tick += (sender, e) => Tick(targs1);

        TickEventArgs targs2 = new TickEventArgs(lbl2_up_time, _elapsedTime_up2);
        timer_up2.Tick += (sender, e) => Tick(targs2);

        TickEventArgs targs3 = new TickEventArgs(lbl3_up_time, _elapsedTime_up3);
        timer_up3.Tick += (sender, e) => Tick(targs3);

        TickEventArgs targs4 = new TickEventArgs(lbl4_up_time, _elapsedTime_up4);
        timer_up4.Tick += (sender, e) => Tick(targs4);

        TickEventArgs targs5 = new TickEventArgs(lbl5_up_time, _elapsedTime_up5);
        timer_up5.Tick += (sender, e) => Tick(targs5);

这不起作用,因为我超出了界限 (5)

        targs[0] = new TickEventArgs(lbl1_up_time, _elapsedTime_up1);
        targs[1] = new TickEventArgs(lbl2_up_time, _elapsedTime_up2);
        targs[2] = new TickEventArgs(lbl3_up_time, _elapsedTime_up3);
        targs[3] = new TickEventArgs(lbl4_up_time, _elapsedTime_up4);
        targs[4] = new TickEventArgs(lbl5_up_time, _elapsedTime_up5);

        timers[0] = timer_up1;
        timers[1] = timer_up2;
        timers[2] = timer_up3;
        timers[3] = timer_up4;
        timers[4] = timer_up5;

        int i = 0;

        for (i = 0; i <= 4; i++)
        {
            timers[i].Tick += (sender, e) => Tick(targs[i]);
        } 
4

2 回答 2

10

这来自 lambda 表达式;i 在所有人之间共享。到函数执行时,它们基本上被称为timers[i].Tick += (sender, e) => Tick(targs[5]).

为避免这种情况,请创建一个局部范围的变量 ( int locali = i) 并在您的行中使用它。这将确保每个 lambda 表达式实际上都获得了您期望的值。

for (i = 0; i <= 4; i++)
{
    int locali = i;
    timers[locali].Tick += (sender, e) => Tick(targs[locali]);
} 

i在退出之前从循环的最后一次迭代变为 5。自然,你没有targs[5]元素,所以它抛出一个IndexOutOfRangeException.

从技术上讲,您不需要使用localitimers[i].Tick部分,因为它会立即进行评估,但我个人觉得将两者混合起来会令人困惑。


关于概念的一些额外阅读:

foreach 标识符和闭包

关闭被认为有害的循环变量

于 2013-08-24T23:21:33.177 回答
8

在这种情况下只有一个i,并且所有的 lambdas 都在捕获相同的值。使用作用域为循环的局部变量,以便每个 lambda 具有不同的副本

for (i = 0; i <= 4; i++)
{
  int j = i;
  timers[j].Tick += (sender, e) => Tick(targs[j]);
}
于 2013-08-24T23:21:21.987 回答