делегат события (в) равенство? - PullRequest
2 голосов
/ 28 сентября 2010

Может ли кто-нибудь объяснить значение следующей части кода:

private event UserChangedHandler m_UserChanged;
public event UserChangedHandler UserChanged
{
  add
  {
      if (m_UserChanged != value)
      {
        m_UserChanged += value;
      }
  }
}

спасибо

Ответы [ 2 ]

4 голосов
/ 28 сентября 2010

add { } - это конструкция, очень похожая на get { } для свойств, за исключением добавления работ для событий.Здесь вы определяете пользовательскую функциональность при добавлении делегатов на событие.

В этом случае тело этого метода предотвращает последовательных дубликатов (то есть вы не можете зарегистрировать один и тот же метод / обработчик дважды в строке ).

Итак, в этом примере:

public void HandlerUserChanged(object o, UserChangedEventArgs args)
{
     // some code
}

public void HandlerUserChanged2(object o, UserChangedEventArgs args)
{
     // some code
}

Позже:

UserChanged += HandleUserChanged;
UserChanged += HandleUserChanged;
UserChanged(this, new UserChangedEventArgs());

Метод HandleUserChanged будет срабатывать только один раз, даже если вы зарегистрировали его дважды.Нормальное событие (без add { }) вызовет функцию дважды.

Однако:

UserChanged += HandleUserChanged;
UserChanged += HandleUserChanged2;
UserChanged += HandleUserChanged;
UserChanged(this, new UserChangedEventArgs());

позволит дважды запустить HandleUserChanged, потому что последний зарегистрированный обработчик isn 'когда-либо добавляемый.Оператор == для событий работает с обработчиком LAST. (Спасибо Матфею за то, что вы обратили на это внимание)

0 голосов
/ 28 сентября 2010

Мне кажется странным, что m_UserChanged объявлен как событие, а не просто как экземпляр делегата (это правильная терминология ... я запутался с делегатами).События аналогичны простой модели Property в том, что они по существу обертывают базовые поля в паре прозрачных методов.

Насколько я понимаю, .Net позволяет создавать неявные (анонимные?) События и свойства, принимая что-то вроде этого:

public int Value { get; set;}
public event EventHandler ValueChanged;

, а затем создавая соответствующие базовые объекты-заполнители.чтобы сгенерировать что-то более похожее на это:

private int _Value;
public int Value { get { return _Value;} set { _Value = value;}}

private EventHandler _ValueChanged;
public event EventHandler ValueChange { add { _ValueChanged += value;} remove { _ValueChanged -= value;}}

Базовый объект, конечно, может быть определен явно, но то, как выглядит пример кода выше, является чем-то вроде сочетания явного и неявного объявления событияпохоже, что на самом деле делается следующее (как бы за кадром):

private UserChangedHandler _m_UserChanged; 
private event UserChangedHandler m_UserChanged { add { _m_UserChanged += value;} remove { _m_UserChanged -= value;}}
public event UserChangedHandler UserChanged 
{ 
  add 
  { 
      if (m_UserChanged != value) 
      { 
        m_UserChanged += value; 
      } 
  } 
} 

Это не имеет большого значения в общем плане вещей, я не думаю, но похоже, чтонедосмотр.

...