Конвенция метода повышения обработчика событий

Я просто просматривал и столкнулся с этим вопросом:

Действие по сравнению с событием делегата

Ответ от nobug включал этот код:

protected virtual void OnLeave(EmployeeEventArgs e) {
  var handler = Leave;
  if (handler != null)
    handler(this, e);
}

Resharper также генерирует подобный код, когда использование "создает повышение метода" быстрое исправление.

Мой вопрос, почему эта строка необходима?:

var handler = Leave;

Почему это лучше, чем запись этого?:

protected virtual void OnLeave(EmployeeEventArgs e) {
  if (Leave != null)
    Leave(this, e);
}

6
задан Community 23 May 2017 в 10:24
поделиться

3 ответа

Это лучше, потому что существует небольшая вероятность того, что Leave станет нулевым после нулевой проверки, но перед вызовом (что приведет к код для создания исключения NullReferenceException ). Поскольку тип делегата неизменяем, если вы сначала назначите его переменной, эта возможность исчезнет; на вашу локальную копию не повлияют никакие изменения в Оставьте после назначения.

Обратите внимание, что этот подход также создает проблему в обратном направлении; это означает, что существует (крошечная, но существующая) вероятность того, что обработчик события будет вызван после того, как он будет отсоединен от события . Этот сценарий, конечно, также должен быть обработан изящно.

12
ответ дан 8 December 2019 в 12:59
поделиться

Вот отличное объяснение Эрика Липперта:

События и гонки

1
ответ дан 8 December 2019 в 12:59
поделиться

В многопоточном приложении вы можете получить исключение с нулевой ссылкой, если вызывающий объект отменяет регистрацию в событии. Присваивание локальной переменной защищает от этого.

Скорее всего, вы никогда этого не увидите (пока это не причинит вам наибольшую боль). Вот способ взглянуть на это, который показывает проблему ...

protected virtual void OnLeave(EmployeeEventArgs e) {
  if (Leave != null) //subscriber is registered to the event
  {
    //Subscriber unregisters from event....
    Leave(this, e); //NullReferenceException!
  }
}
5
ответ дан 8 December 2019 в 12:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: