C# IEnumerable的匿名方法变量作用域问题

发布于 2024-08-28 15:25:13 字数 485 浏览 5 评论 0原文

我正在尝试迭代所有组件,并为那些实现 ISupportsOpen 的组件允许打开项目。 问题是当调用匿名方法时,组件变量始终是相同的元素(来自 IEnumerable 的外部范围),

foreach (ISupportsOpen component in something.Site.Container.Components.OfType<ISupportsOpen>())
{
    MyClass m = new MyClass();  
    m.Called += new EventHandler(delegate(object sender, EventArgs e)
    {                           
        if (component.CanOpenProject(..)) component.OpenProject(..);
    });

    itemsList.Add(m);
}

请问应该如何解决?

I'm trying to iterate through all components and for those who implements ISupportsOpen allow to open a project.
The problem is when the anonymous method is called, then the component variable is always the same element (as coming from the outer scope from IEnumerable)

foreach (ISupportsOpen component in something.Site.Container.Components.OfType<ISupportsOpen>())
{
    MyClass m = new MyClass();  
    m.Called += new EventHandler(delegate(object sender, EventArgs e)
    {                           
        if (component.CanOpenProject(..)) component.OpenProject(..);
    });

    itemsList.Add(m);
}

How should it be solved, please?

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

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

发布评论

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

评论(1

惯饮孤独 2024-09-04 15:25:13

只是不要 关闭循环变量 - 复制它:

foreach (ISupportsOpen component in 
         something.Site.Container.Components.OfType<ISupportsOpen>())
{
    ISupportsOpen copy = component;
    MyClass m = new MyClass();  
    m.Called += new EventHandler(delegate(object sender, EventArgs e)
    {                           
        if (copy.CanOpenProject(..)) copy.OpenProject(..);
    });

    itemsList.Add(m);
}

这样您就可以为循环的每次迭代获得copy变量的新“实例” - 因此每个委托都会捕获该不同的实例。以前,每个代表都捕获相同的变量。

(这在某种程度上是一个重复的问题,但这是一种相对难以搜索的问题,所以我很乐意多次回答它。)

Just don't close over the loop variable - copy it:

foreach (ISupportsOpen component in 
         something.Site.Container.Components.OfType<ISupportsOpen>())
{
    ISupportsOpen copy = component;
    MyClass m = new MyClass();  
    m.Called += new EventHandler(delegate(object sender, EventArgs e)
    {                           
        if (copy.CanOpenProject(..)) copy.OpenProject(..);
    });

    itemsList.Add(m);
}

This way you get a new "instance" of the copy variable for each iteration of the loop - so each delegate will capture that different instance. Before, every delegate was capturing the same variable.

(This is in some ways a duplicate question, but it's the kind of problem which is relatively hard to search for, so I'm happy to answer it many times.)

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