我有一个具有多播委托的类:
class Signaler
{
public delegate bool SomeAction(string s);
public SomeAction Actors {get; set;}
void SignalActors()
{
Actors("blah blah");
}
}
我想做的是当一个actor在处理其动作时返回false时,从Actors中删除一个actor。在SignalActors()
函数中执行此操作的好方法是什么?
更新:基于John Skeet解决方案的可能解决方案:
class Signaler
{
public delegate bool SomeAction(string s);
public SomeAction Actors {get; set;}
void SignalActors()
{
SomeAction canceledSubscriptions=null;
if (Actors!=null)
foreach (SomeAction actor in Actors.GetInvocationList())
if (!actor("Blah blah blah"))
canceledSubscriptions+=actor;
if (canceledSubscriptions!=null)
foreach (SomeAction actor in canceledSubscriptions.GetInvocationList())
Actors-=actor;
}
}
答案 0 :(得分:2)
最简单的方法可能是实际建立一个返回true
的所有代理的新委托:
void SignalActors()
{
SomeAction newActors = null;
foreach (SomeAction actor in Actors.GetInvocationList())
{
if (actor("Blah blah blah"))
{
newActors += actor;
}
}
Actors = newActors;
}
编辑:这比使用-=
简单的原因是它在排序方面显然是正确的。尽管+=
总是添加到调用列表的末尾,-=
也会从调用列表的末尾开始...所以如果你在转发顺序中删除了actor,你可能有问题。假设我们有以下演员:
A - returns false
B - returns true
C - returns true
A - (duplicate of the first) returns true this time
你应该以{B,C,A}结尾,但如果你从{A,B,C,A}中减去A,你最终会得到{A,B,C} 。我的方法避免了这个问题。