c# – 在for循环中分配委托的问题

前端之家收集整理的这篇文章主要介绍了c# – 在for循环中分配委托的问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个能够插件(MEF)的应用程序.
插件是导入服务的 WPF UserControls.

用户可以从应用程序的主菜单中选择所需的插件.

为此,我使用以下循环:

foreach(IToolPlugin Plugin in ToolPlugins)
{
    Plugin.Init();
    MenuItem PluginMenuItem = Plugin.MenuItem; //New MenuItem but with Header set.
    PluginMenuItem.Click += new RoutedEventHandler(delegate(object o,RoutedEventArgs e) { DoSomething(Plugin.Control);});
    PluginsMenu.Items.add(PluginMenuItem);
}

这对于单个项目非常好.但是,只要我有一个以上的插件,所有菜单项都会执行最后一个循环的委托.或者至少使用最后一个循环的Plugin.Control.

我怎样才能解决这个问题?
谢谢你的帮助.

解决方法

在循环的每次迭代中,在关闭中使用它之前,必须“捕获”迭代值的值.否则,每个委托中的插件将指向插件的最后一个值,而不是创建匿名函数时它所持有的值.

您可以在此处阅读Eric Lippert的更深入的解释:

Closing over the loop variable considered harmful – Fabulous Adventures in Coding

简而言之,编写foreach循环的正确方法是:

foreach(IToolPlugin Plugin in ToolPlugins)
{
    Plugin.Init();
    MenuItem PluginMenuItem = Plugin.MenuItem;

    IToolPlugin capturedPlugin = Plugin;

    PluginMenuItem.Click += 
        new RoutedEventHandler(delegate(object o,RoutedEventArgs e) {
            DoSomething(capturedPlugin.Control);
        });

    PluginsMenu.Items.add(PluginMenuItem);
}

猜你在找的C#相关文章