Удаление многоадресного делегата на основе возвращаемого значения - PullRequest
0 голосов
/ 17 ноября 2010

У меня есть класс с делегатом многоадресной рассылки:

class Signaler
{
  public delegate bool SomeAction(string s);
  public SomeAction Actors {get; set;}

  void SignalActors()
  {
    Actors("blah blah");
  }
}

Я хотел бы удалить актера из Actors, когда этот актер возвращает false как часть обработки своего действия.Какой хороший способ сделать это в функции SignalActors()?

Обновление : возможное решение на основе решения Джона Скита:

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 Ответ

2 голосов
/ 17 ноября 2010

Возможно, самый простой способ - это создать нового делегата из всех возвращающих true:

void SignalActors()
{
    SomeAction newActors = null;
    foreach (SomeAction actor in Actors.GetInvocationList())
    {
        if (actor("Blah blah blah"))
        {
            newActors += actor;
        }
    }
    Actors = newActors;
}

РЕДАКТИРОВАТЬ: Причина, по которой это проще, чем использование -=, заключается в том, что это, очевидно, правильно с точки зрения порядка. Принимая во внимание, что += всегда добавляет в конец списка вызовов, -= также убирает из конца списка вызовов ... поэтому, если вы удалите актеров в порядке forward , у вас может возникнуть проблема , Предположим, у нас есть следующие актеры:

A - returns false
B - returns true
C - returns true
A - (duplicate of the first) returns true this time

Вы должны в итоге получить {B, C, A}, но если вы вычтете A из {A, B, C, A}, вы получите {A, B, C}. Мой подход позволяет избежать этой проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...