c# - for循环中事件处理程序的匿名方法

标签 c# winforms event-handling

这可以在 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]);
        } 

最佳答案

这来自 lambda 表达式; is shared between all of them .当函数被执行时,它们实际上被调用为 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

从技术上讲,您不需要对 timers[i].Tick 部分使用 locali,因为它会立即求值,但我个人觉得混合使用两个。


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

The foreach identifier and closures

Closing over the loop variable considered harmful

关于c# - for循环中事件处理程序的匿名方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18424111/

相关文章:

javascript - 如何让用户输入文本来搜索数组对象,如果匹配则输出?请纯Javascript

c# - 如何在 ASP.NET MVC 模型验证中检查字符串是否包含 HTML 代码?

c# - 如何将对象列表作为函数中的参数传递,然后使用对象的属性 C#

c# - fatal error : Unhandled Access Exception in AutoCAD C#. NET 插件

c# - 用具体类实现接口(interface)方法

c# - 表单之间的通信

winforms - 使用 marshal_as 和编码进行字符串编码

c# - 在tabcontrol c#中的选项卡标题中放置粗体字体

mongodb - 监视 MongoDB 更改流

c++ - 信号处理程序与虚函数和继承(事件处理)