Делегат событий (в) равенстве?
-
26-09-2019 - |
Вопрос
Может ли кто-то объяснить значение следующей части кода:
private event UserChangedHandler m_UserChanged;
public event UserChangedHandler UserChanged
{
add
{
if (m_UserChanged != value)
{
m_UserChanged += value;
}
}
}
Спасибо
Решение
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
Чтобы пожарить дважды, потому что последний зарегистрированный обработчик никогда не добавляется. Оператор == на событиях работает на последнем обработчике. (Спасибо Маттею за привлечение этого к вниманию)
Другие советы
Это поражает меня как странно, что M_USERChanged объявляется как событие, а не просто экземпляр делегата (в том, что правильная терминология ... я запутался с делегатами). События аналогичны простому модели свойства в том, что они по существу охватывают базовые поля в паре прозрачных методов.
То, как я понимаю, .NET позволяет создавать Improcit (анонимное?) Событие и свойства, взяв что-то подобное:
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;
}
}
}
Это не имеет значения в Гранд-схеме вещей, я не думаю, но это похоже на надзор.