Если событие помечено ключевым словом C # event , то снаружи объекта нет возможности увидеть подписчиков - необходимая информация просто не видна.
Изнутри это можно сделать, хотя это сложно и зависит от деталей реализации, которые могут измениться (хотя они еще не изменились).
Обходной путь, который может быть полезен для вас, заключается в том, что он действителен для удаления обработчика, которого нет - исключение не выдается.
Итак, этот код действителен:
myConnection.Closing -= ConnectionClosingHandler;
myConnection.Closing += ConnectionClosingHandler;
Если вы уже подписаны на событие, первая строка удаляет подписку.
Если вы не уже подписаны на событие, первая строка ничего не делает.
Затем вторая строка подключает новую подписку, и вы гарантированно не будете получать уведомления несколько раз.
Чтобы ответить на последний пункт, когда вы объявляете нормальное событие:
public event PropertyChangedEventHandler Changed;
Компилятор создает переменную-член типа PropertyChangedEventHandler
, в которой хранятся все подписчики. Вы можете взять на себя хранение, если хотите:
public event PropertyChangedEventHandler Changed
{
add { ... }
remove { ... }
}
Использование -=
и +=
для изменения подписки не является синтаксическим сахаром - делегаты являются неизменяемыми, и при добавлении или удалении обработчика возвращается новый экземпляр. Посмотрите Delegate
и MulticastDelegate
(обе ссылки MSDN) для получения дополнительной информации о том, как это работает.