在foreach循环中始终使用相同的值调用事件处理程序 [英] Event handler always called with the same value in foreach loop
问题描述
我想将一组回调函数绑定到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屋!