EventInfo.GetRaiseMethod() всегда null

У меня есть:

event EventHandler MyEvent;

MyEvent += new EventHandler(someHandler);

if(this.GetEvent("MyEvent").GetRaiseMethod() == null)
{
  // Always true...
}

Но почему? После добавления обработчика нельзя GetRaiseMethod() установить someHandler MethodInfo?

Ответ 1

Это причуда С#, она не поддерживает функции повышения доступа. Добавляйте и удаляйте. Другие языки .NET, такие как VB.NET, F # и С++/CLI, поддерживают их, и они хорошо определены в спецификации CLI с именем "fire" в этом.

Трудно объяснить, почему команда С# пропустила его, я никогда не видел для этого хорошего объяснения. Чистая спекуляция: возможно, это связано с их желанием избежать затрат на построение аргументов события для события, которое никто не подписывал. Очень часто в графических интерфейсах. Это немного потеря, сотни тысяч часов, должно быть, были потеряны программистами на С#, которые пишут стандартный шаблон событий рейза, а также диагностируют NRE, когда они забыли проверить нуль. Оператор elvis (?.) в С# v6, наконец, упростил работу.

Anyhoo, вы никогда не получите ничего, кроме null, из GetRaiseMethod(), если вы отражаете код, написанный на С#. Однако вы всегда получите ненулевое значение, когда оно было написано на VB.NET, F # или С++/CLI. Вам нужно будет выкопать переменную делегата, если вам нужно поднять событие с отражением, что может быть болезненным. Если использовались автогенераторы с добавлением/удалением, то переменная поддержки имеет то же имя, что и событие, и вы можете получить ее с помощью Type.GetField(), используя BindingFlags.NonPublic | BindingFlags.Instance.

Ответ 2

Метод повышения является одним из аксессуаров, упомянутых в спецификации CLI, в дополнение к "добавлению" и "удалению" - однако большинство событий просто не реализуют эту функцию. В частности, С# специально не поддерживает это - так что да: всегда будет возвращать null.