0

注意:这更像是一个好奇的问题。

鉴于List<Window>每个窗口都有一个附加到关闭事件的事件,该事件从集合中删除窗口,您如何使用委托/事件来推迟关闭事件的执行,直到集合被迭代?

例如:

public class Foo
{

    private List<Window> OpenedWindows { get; set; }

    public Foo()
    {
        OpenedWindows = new List<Window>();
    }

    public void AddWindow( Window win )
    {
        win.Closed += OnWindowClosed;
        OpenedWindows.Add( win );
    }

    void OnWindowClosed( object sender, EventArgs e )
    {
        var win = sender as Window;

        if( win != null )
        {
            OpenedWindows.Remove( win );
        }
    }

    void CloseAllWindows()
    {
        // obviously will not work because we can't 
        // remove items as we iterate the collection 
        // (the close event removes the window from the collection)
        OpenedWindows.ForEach( x => x.Close() );

        // works fine, but would like to know how to do
        // this with delegates / events.
        while( OpenedWindows.Any() )
        {
            OpenedWindows[0].Close();
        } 
    }

}

具体来说,在该CloseAllWindows()方法中,如何迭代集合以调用 close 事件,但将引发的事件推迟到集合完全迭代?

4

1 回答 1

0

大概您试图避免在第一种情况下出现“集合已修改”异常。

实际上,“推迟”此操作的唯一方法是制作集合的副本,这涉及完全迭代原始集合并将项目添加到新集合中:

var openedWindowsCopy = new List<Window>(OpenedWindows);
foreach (var window in openedWindowsCopy)
    window.Close();

此外,您的第二种方法是有效的,尽管通常当您需要清理索引集合中的实例时,例如 a List<T>,您只需倒计时即可:

for (int i = OpenedWindows.Count - 1; i >= 0; i--)
    OpenedWindows[i].Close();

就个人而言,我认为没有理由让更多代表使问题复杂化。

于 2010-04-11T22:59:26.060 回答