Риск перезаписи делегата в C#
Если делегат объявлен как обычное public поле,
любой код может присвоить ему новое значение или
null. Подписчики, добавленные через +=,
исчезнут после простого =.
Запишем класс с открытым делегатом и покажем, как внешнее присваивание обнуляет цепочку:
void OnPing() {
Console.WriteLine("ping");
}
Hub hub = new Hub();
hub.Ping += OnPing;
hub.Ping = null;
hub.Ping?.Invoke();
class Hub {
public Action? Ping;
}
Именно поэтому для уведомлений поле оформляют как событие: снаружи нельзя заменить весь список обработчиков, а оповещение выполняет класс-владелец.