在foreach循环中始终使用相同的值调用事件处理程序 [英] Event handler always called with the same value in foreach loop

查看:45
本文介绍了在foreach循环中始终使用相同的值调用事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将一组回调函数绑定到C#中的GUI元素,每个回调函数使用不同的参数调用相同的处理函数.

I want to bind a set of callback functions to GUI elements in C#, each calling the same processing function with a different argument.

拼写方式

# Assign element #1 to widget

widget.Click += () => {ProcessClick(1) ;} ;

# Assign element #2 to widget

widget.Click += () => {ProcessClick(2) ;} ;

...

似乎是多余的.但是,

Widget widget ;

foreach (int i in new List<int>() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} )
{
    # Assign element i to widget

    widget.Click += () => {ProcessClick(i) ;} ;
}

将不起作用,因为一旦调用任何回调,循环将失效,从而导致每个小部件都调用 ProcessClick(9).

will not work, as the loop will have expired once any callback is being called, resulting in a call of ProcessClick(9) for each widget.

我觉得应该有一个简单的解决方案,但是我被困住了.

I feel there should be a simple solution for this, but I'm stuck.

如何将回调函数绑定到GUI元素,而每个GUI元素使用不同的参数调用函数,而又不会完全拼写出来?

How can I bind callback functions to the GUI elements each calling a function with a different argument without spelling them all out?

推荐答案

i 在循环过程中被您的委托捕获.您需要在循环中将其值复制到局部变量以使其起作用:

i is captured by your delegate during the loop. You'll need to copy its value to a local variable in your loops to make it work:

Widget widget ;

foreach (int i in new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } )
{
    # Assign element i to widget

    int index = i;
    widget.Click += () => {ProcessClick(index) ;} ;
}

可以在此处埃里克·利珀的博客.在后者上,您还将找到有关C#团队在C#5中所做的重大更改的信息,变量在逻辑上位于循环内(如DavidG所指出的).

More info on variables capture can be found here and on Eric Lipper's blog. On the latter you'll also find info about the breaking changes the C# team made in C# 5 for which the variable is logically inside the loop (as noted by DavidG).

这篇关于在foreach循环中始终使用相同的值调用事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆