根据返回值删除组播委托

时间:2010-11-17 18:23:59

标签: c# c#-4.0

我有一个具有多播委托的类:

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;
  }
} 

1 个答案:

答案 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} 。我的方法避免了这个问题。