(Это все из С # точки зрения.)
У меня есть article about the differences between events and delegates. Это охватывает все, о чем упоминалось ниже, более подробно.
В принципе, мне нравится думать о том, что событие похоже на свойство - это пара методов, вот и все. Вместо get/set событие имеет add/remove, что означает «добавить обработчик событий» и «удалить этот обработчик событий». В основе всего, все это событие.
C# также имеет поле типа события которые ярлык:
public event EventHandler Foo;
объявляет как поле и события, с почти тривиальными добавить/удалить реализацию. Внутри класса ссылка на Foo
относится к полю. Вне класса, ссылаясь на Foo
, это событие.
Основная идея состоит в том, что событие позволяет другому коду подписаться и отказаться от него, передав делегат (событие обработчик). Как правило, подписка реализуется путем создания нового многоадресного делегата, содержащего список обработчиков событий, а также новый обработчик событий .Так что, если вы храните обработчик событий в поле под названием myEventHandlers
, реализация подписки может быть:
myEventHandlers += value;
Аналогично отписка обычно включает в себя создание нового многоадресного делегата без указанного обработчика:
myEventHandlers -= value;
Затем, когда вы хотите поднять/запустить событие, вы просто вызываете этот делегат многоадресной передачи - обычно с проверкой недействительности, чтобы исключить исключение, если никто не подписался:
EventHandler handler = myEventHandlers;
if (handler != null)
{
// You could pass in a different "sender" and "args" of course
handler(this, EventArgs.Empty);
}
Используя события, подписчики не знают друг о друге и не могут сами поднимать событие (обычно). Другими словами, это шаблон инкапсуляции, который получил статус как на языке, так и на платформе.
Нет, события * не являются * делегатами. События - это методы добавления/удаления, в основном. Говорить о том, что события являются делегатами, - это сказать, что свойства - это поля. –
Свойства IMHO ДОЛЖНЫ вести себя как поля, точно так же, как события должны вести себя как многоадресные делегаты. Иначе это вводит в заблуждение для пользователя класса, так как доступ к свойствам и полям похож на источник, как отправка события и отправка делегата. Это не означает, что для свойства или события необходимо использовать реализацию по умолчанию (поле поддержки, поддержка многоадресного делегата). Это просто означает «свойство/поле: Получить/установить значение без побочных эффектов» и «event/delegate: запустить обратный вызов». Со свойствами/событиями язык дает вам много веревки, которые вы можете использовать разумно или повеситься. – froh42