开发者

Dynamically Generating Buttons that Call a Lambda Function -- Variable Scope

I have a situation where I have someFunction(int), and I need to generate p开发者_如何转开发rogrammatically n buttons that will call it. What this means is that I want to create buttons B1, B2, ... Bn that call someFunction(1), someFunction(2), ... someFunction(n) when clicked.

This is how I attempted to do this (semi-pseudocode):

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

What bugs me about this is that when I click on the first button (B1), with a debugger over someFunction(i), it tells me that it's calling someFunction(n + 1).

I'm not sure why this is, or how to fix it. The work-around I use is to use, instead of someFunction(i), someFunction(int.Parse(i.ToString()) (to create a copy of i). But this seems shady to me, because integers should be value types.


I believe you understand WHY this happens. The problem is it captures the variable i itself, not its value. The workaround that seems better (without toString and int.parse) to me is to declare another local var that copies i

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

This way the captured variable will be locali and it will remain the same across the loop.


Stormbreaker is correct, for more information see Eric Lippert's answer to this question

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜