2013-02-14 3 views
10

у меня есть:EventInfo.GetRaiseMethod() всегда нулевой

event EventHandler MyEvent; 

MyEvent += new EventHandler(someHandler); 

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

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

ответ

9

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

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

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

+0

Не очень хорошо знакомый с VB.NET, я попытался написать некоторый код VB.NET с помощью «Event», пытаясь получить такой случай, чтобы 'GetRaiseMethod()' что-то возвращал. Я попробовал инструкцию 'AddHandler', но я также попробовал предложение' Handles'. Первый, похоже, подписывается на событие только во время выполнения (например, на C#, я думаю?), Но последнее кажется более перспективным в том, что он объявляет отношение во время компиляции. Тем не менее я не имел успеха с 'GetRaiseMethod', он возвращает' Nothing' (null). Как создать пример, чтобы показать, что 'GetRaiseMethod' может быть нетривиальным для кода, который поступает из VB.NET? –

+0

Прекрасно работает, когда я пытаюсь, вы должны задать вопрос об этом. –

+0

Хорошо, я разместил вопрос в новой теме. –

3

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

+0

Возможно, вы захотите добавить, что вы говорите о спецификации CLI, а не спецификации C#. – svick