[英]Anonymous method for event handler in for loop
Can this be done in a for loop? 这可以在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);
This doesnt work because i is out of bounds (5) 这不起作用,因为我超出界限(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]);
}
This is coming from the lambda expression; 这来自lambda表达式;
i
is shared between all of them . i
在所有人之间分享 。 By the time the function is executed they're essentially being called like timers[i].Tick += (sender, e) => Tick(targs[5])
. 当函数执行时,它们基本上被称为
timers[i].Tick += (sender, e) => Tick(targs[5])
。
To avoid this, create a locally scoped variable ( int locali = i
) and use that in your line instead. 要避免这种情况,请创建一个本地范围的变量(
int locali = i
)并在您的行中使用它。 This will make sure that each lambda expression actually gets the value you expect. 这将确保每个lambda表达式实际获得您期望的值。
for (i = 0; i <= 4; i++)
{
int locali = i;
timers[locali].Tick += (sender, e) => Tick(targs[locali]);
}
i
becomes 5 from the last iteration of your loop before exiting. 在退出之前,
i
从循环的最后一次迭代变为5。 Naturally, you don't have a targs[5]
element, so it throws an IndexOutOfRangeException
. 当然,您没有
targs[5]
元素,因此它会抛出IndexOutOfRangeException
。
Technically, you don't need to use locali
for the timers[i].Tick
part since it's evaluated immediately, but I personally find it confusing to mix the two. 从技术上讲,你不需要使用
locali
作为timers[i].Tick
因为它会被立即评估,所以我觉得很困惑。
Some additional reading on the concepet: 关于概念的一些额外阅读:
The foreach identifier and closures foreach标识符和闭包
Closing over the loop variable considered harmful 关闭循环变量被认为是有害的
There is only one i
in this case and all of the lambdas are capturing the same value. 在这种情况下只有一个
i
,并且所有lambda都捕获相同的值。 Use a local that is scoped to the loop so that each lambda has a different copy 使用作用于循环的本地,以便每个lambda具有不同的副本
for (i = 0; i <= 4; i++)
{
int j = i;
timers[j].Tick += (sender, e) => Tick(targs[j]);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.