在foreach循环中,总是使用相同的值调用事件处理程序

本文关键字:值调用 程序 事件处理 循环 foreach | 更新日期: 2023-09-27 18:24:05

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

拼写方式

# 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)

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

如何将回调函数绑定到GUI元素,每个元素都用不同的参数调用一个函数,而不将它们全部拼写出来?

在foreach循环中,总是使用相同的值调用事件处理程序

i在循环期间由您的代理捕获。您需要将其值复制到循环中的本地变量中,以使其工作:

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) ;} ;
}

关于变量捕获的更多信息可以在这里和Eric Lipper的博客上找到。在后者中,您还可以找到关于C#团队在C#5中所做的突破性更改的信息,对于这些更改,变量在逻辑上位于循环中(如DavidG所述)。