不同“执行上下文”的问题循环内的匿名方法

发布于 2024-10-06 21:16:49 字数 736 浏览 2 评论 0原文

我在循环中使用匿名方法时遇到问题。

以下代码只是为了说明我的问题:

private void Form1_Load(object sender, EventArgs e)
{
    List<string> bassists = new List<string>(){
        "Jaco Pastorius", 
        "Marcus Miller", 
        "Flea", 
        "Vicor Wooten"
    };

    foreach (string item in bassists)
    {
        this.button1.Click += (s, ea) => Output(s, ea, item); 
    }
}

private void Output(object s, EventArgs e, string item)
{
    this.listBox1.Items.Add(item);
}

当我单击按钮时,输出为:

维克多·伍顿
维克多·伍顿
维克多·伍顿
维克多·伍顿

代替:

雅科·帕斯托里斯
马库斯·米勒
跳蚤
维科·伍顿

我的问题的要点是不同的执行上下文。我知道我的例子很愚蠢。

I have a problem with an anonymous method within a loop.

The following code is just to illustrate my problem:

private void Form1_Load(object sender, EventArgs e)
{
    List<string> bassists = new List<string>(){
        "Jaco Pastorius", 
        "Marcus Miller", 
        "Flea", 
        "Vicor Wooten"
    };

    foreach (string item in bassists)
    {
        this.button1.Click += (s, ea) => Output(s, ea, item); 
    }
}

private void Output(object s, EventArgs e, string item)
{
    this.listBox1.Items.Add(item);
}

And when I click into the button, the output is:

Victor Wooten
Victor Wooten
Victor Wooten
Victor Wooten

instead of:

Jaco Pastorius
Marcus Miller
Flea
Vicor Wooten

The main point of my problem is the differents execution context. I know my example is stupid.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

看轻我的陪伴 2024-10-13 21:16:49

这就是捕获变量问题。通过更改为修复

foreach (string item in bassists)
{
    this.button1.Click += (s, ea) => Output(s, ea, item); 
}

foreach (string item in bassists)
{
    string currentItem = item;
    this.button1.Click += (s, ea) => Output(s, ea, currentItem); 
}

问题:这是问题的解释: 关闭循环变量被认为是有害的。通过将局部变量 currentItem 放入循环范围并关闭它,我们现在捕获该变量而不是循环变量。

This is the captured variable problem. Fix it by changing

foreach (string item in bassists)
{
    this.button1.Click += (s, ea) => Output(s, ea, item); 
}

to

foreach (string item in bassists)
{
    string currentItem = item;
    this.button1.Click += (s, ea) => Output(s, ea, currentItem); 
}

Here is an explanation of the issue: Closing over loop variable considered harmful. By putting the local variable currentItem in the scope of the loop and closing over that, we now capture that variable instead of the loop variable.

吃不饱 2024-10-13 21:16:49

您的问题是您正在循环中创建新的处理程序,这是不必要且危险的。

此外,您还创建了一个匿名方法,该方法在循环中具有硬编码的值。那就更糟了。

Your problem is that you are creating new handlers in the loop, that is unnecessary and dangerous.

Also you are creating an anonymous method which has the value in the loop hard-coded. That is worse.

妄司 2024-10-13 21:16:49

无论如何,杰森的答案都是正确的。这是变量捕获的问题。这主要发生在线程和匿名方法两种情况下

In whatever cases Jason's answer is correct. It is problem of variable capturing. This will majorly occur in two situation Threading and Anonymous methods

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文