Как EventHandler узнает, что оператор allow = может быть указан только в определении класса? - PullRequest
1 голос
/ 02 мая 2009

Я начал с вопроса и, набрав вопрос, нашел ответ, но вместо удаления подумал, что это может быть полезно для А) получения подтверждения и Б) для помощи другим.

Если у меня есть событие, и в нескольких местах приложения добавлены прослушиватели, каков наилучший способ удалить всех прослушивателей одновременно? Например, я могу ...

myPage.OnPageOpened += OpenPage;

и позже в моем коде ...

myPage.OnPageOpened -= OpenPage;

Но что, если у меня есть неизвестные сторонние подписчики, и я хочу нажать волшебную кнопку сброса, которая очищает все и запускается с нуля?

Вы можете использовать операторы + = и - = где угодно против EventHandler, потому что перегрузки операторов являются публичными. Оператор = перегружен как частный, его можно вызывать только в определяющем классе.

Так что в определяющем классе я могу использовать это для очистки моего EventHandler.

OnPageOpened = null;

И чтобы раскрыть эту функциональность, я мог бы ...

public void ClearPageOpenedEvents() {
   OnPageOpened = null;
}

Это правильно?

Ответы [ 3 ]

1 голос
/ 02 мая 2009

Да, вы правы. Причина этого заключается в том, что компилятор создает объект private delegate под обложками, например:

private EventHandler pageOpened;

public EventHandler PageOpened
{
    add { pageOpened += value; }
    remove { pageOpened -= value; }
}

Внутри вашего класса у вас есть ссылка на закрытый экземпляр delegate, поэтому вы можете выполнить это задание. Вы определенно хотите использовать метод для очистки целей, если вам нужна эта функциональность; Вы не хотите выставлять себя delegate.

1 голос
/ 02 мая 2009

Это способ сделать это, но как кто-то вне класса узнает, что класс должен отбросить всех своих слушателей событий? Что если кто-то расширяет / использует ваш код, ожидает этого события на постоянной основе?

0 голосов
/ 02 мая 2009

Вы можете использовать оператор присваивания для события, потому что именно так работают добавление и удаление событий. Использование Reflector проливает много света на то, как происходят события в C #.

Учитывая простой класс

public class MyClass
{
  public event EventHandler MyEvent;
}

Следующий код создается при компиляции

public class MyClass
{
  private EventHandler MyEvent;

  public event EventHandler MyEvent;
}

Поэтому, когда вы ссылаетесь на MyEvent, вы ссылаетесь на приватную переменную-делегат MyEvent. Операторы += и -= являются «специальными» (потому что они не являются операторами) и заменяются вызовом методов add и remove, которые создаются для события (которые сами используют оператор присваивания).

[MethodImpl(MethodImplOptions.Synchronized)]
public void add_MyEvent(EventHandler value)
{
  this.MyEvent = (EventHandler) Delegate.Combine(this.MyEvent, value);
}

[MethodImpl(MethodImplOptions.Synchronized)]
public void remove_MyEvent(EventHandler value)
{
    this.MyEvent = (EventHandler) Delegate.Remove(this.MyEvent, value);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...