如何使用委托和/或事件推迟集合中每个项目上事件的执行,直到集合迭代完成?
值得注意:这更像是一个好奇问题。
给定一个 List
例如:
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()
方法中,如何迭代集合以调用关闭事件,但将引发事件推迟到集合完全迭代之后?
Of Note: This is more of a curiosity question than anything else.
Given a List<Window>
where each window has an event attached to the Close Event which removes the window from the collection, how could you use delegates / events to defer the execution of the Close Event until the collection has been iterated?
For example:
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();
}
}
}
Specifically, within the CloseAllWindows()
method, how could you iterate the collection to call the close event, but defer the event being raised until the collection has been completely iterated?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
想必您正在尝试避免第一种情况下的“集合已修改”异常。
实际上,“推迟”此操作的唯一方法是制作集合的副本,这涉及完全迭代原始集合并将项目添加到新集合中:
此外,第二种方法是有效的,尽管通常在需要清理时索引集合(例如
List
)中的实例,您只需通过倒计时即可完成:就我个人而言,我认为没有理由通过更多委托使问题复杂化。
Presumably you're trying to avoid the "Collection was modified" exception in the first case.
Really the only way to "defer" this is to make a copy of the collection, which involves iterating the original collection fully and adding the items to a new collection:
Also, your second method is valid, although typically when you need to clean up instances in an indexed collection such as a
List<T>
, you do it simply by counting down:Personally, I see no reason to complicate the issue with more delegates.