То, что вы просите сделать, на самом деле невозможно с событиями .NET и, вероятно, не так желательно, как вы думаете. Немного предыстории должно помочь объяснить, почему:
Свойства имеют базовый шаблон с операциями get и set. Они вызываются путем доступа к свойству (для получения) и присвоения свойству (для набора):
var x = instance.Prop1; // access
instance.Prop1 = x; // assignment
Когда вы получаете доступ к событию извне класса (т.е. instance.Event
), вам предоставляется «публичное» лицо, которое, как и свойства, имеет две операции: добавить обработчик и удалить обработчик. Они вызываются с использованием операторов +=
и -=
.
instance.Event += this.Handler; // add
instance.Event -= this.Handler; // remove
Важно отметить, что в нем нет операции get - нет способа получить ссылку на событие вне класса ; Вы можете изменять только зарегистрированные обработчики.
Когда вы обращаетесь к событию из класса, вам присваивается «личное» лицо, которое по сути является специальной коллекцией делегатов (указателей функций) для зарегистрированных обработчиков событий. Когда вы вызываете делегата, вы на самом деле просите платформу перебрать зарегистрированные обработчики событий и вызвать их.
if(this.Event != null)
{
this.Event.Invoke(e, args); // raise event
}
Это разделение публичного лица и частного лица - вот что позволяет вам иметь хорошее простое ключевое слово event
, которое волшебным образом дает вам событие. Это также то, что мешает вам передать ссылку на событие вокруг.
Чтобы передать событие в методы регистрации, вы должны передать объект, к которому прикреплено событие. Если у вас есть несколько классов, которые реализуют одно и то же событие, и вы хотите зарегистрировать их все одинаково, вам нужно, чтобы они реализовали интерфейс с событием (да, события могут быть в интерфейсах) и напишите свой метод для принятия интерфейса как аргумент.