动态生成调用Lambda函数的按钮 - 可变范围

时间:2011-05-06 20:47:31

标签: c# delegates parameter-passing lambda

我遇到someFunction(int)的情况,我需要以编程方式生成n按钮来调用它。这意味着我想创建调用B1B2,... {{1}的按钮BnsomeFunction(1),... someFunction(2)点击时。

这就是我尝试这样做的方式(半伪代码):

someFunction(n)

关于这一点的问题是,当我点击第一个按钮(B1),调试器超过for (int i = 1; i <= n; i++) { Button b = new Button(); b.Caption = "Value " + n; // non-WPF: b.Text = "Value " + n; b.Click += (sender, event) => { someFunction(i); } } 时,它会告诉我它正在调用someFunction(i)

我不确定这是为什么,或者如何解决它。我使用的解决方法是使用而不是someFunction(n + 1)someFunction(i)(以创建someFunction(int.Parse(i.ToString())的副本)。但这对我来说似乎是阴暗的,因为整数应该是值类型。

2 个答案:

答案 0 :(得分:2)

我相信你明白为什么会这样。问题是它捕获变量i本身,而不是它的值。对我来说似乎更好(没有toString和int.parse)的解决方法是声明另一个复制i的本地var

for (int i = 1; i <= n; i++) {
Button b = new Button();
  b.Caption = "Value " + n; // non-WPF: b.Text = "Value " + n;
  int locali = i;
  b.Click += (sender, event) => {
    someFunction(locali);
  }
}

这样,捕获的变量将为locali,并且它将在循环中保持不变。

答案 1 :(得分:1)

Stormbreaker是正确的,有关更多信息,请参阅Eric Lippert对此问题的回答

C# lambda, local variable value not taken when you think?