Можно ли подключить анонимного делегата с помощью рефлексии? - PullRequest
3 голосов
/ 01 марта 2011

Из этой статьи MSDN есть довольно много способов подключить делегата с помощью отражения.

Кажется, лучший способ - метод CreateDelegate:

Delegate d = Delegate.CreateDelegate(delegateType, targetObject, handlerMethodName);

В обычных условиях я бы указывал на метод-обработчик, который находится в классе targetObject. Но что, если делегат был создан анонимно? Пример:

public delegate void SelectedVehiclesCollectionDelegate(string query, List<Vehicles> list);
...
myObject.SelectedVehiclesCollection = (query, list) =>
                    {
                      //assign list of vehicles to list matching query
                    };  

В определении класса нет метода, на который ссылается делегат. Мне нужно вызвать этот делегат, который неизвестен во время выполнения, в результате получается список элементов.

Хорошо, похоже, моя терминология одолела меня. Я не собирался создавать обработчик, а вызывал то, что уже есть (ответ Томаса Петричека все же дает мне хорошее понимание).

Ответы [ 2 ]

2 голосов
/ 01 марта 2011

Учитывая ваш комментарий, похоже, что это примерно вызов делегата, а не создания , в этом случае Delegate.DynamicInvoke, вероятно, то, что вы ' после, если вы действительно не знаете соответствующий тип делегата во время компиляции.

Если вы действительно знаете соответствующий тип делегата, но не имя свойства, вы можете привести:

MyDelegate handler = (MyDelegate) propertyInfo.GetValue(obj, null);
handler(...); // Call as normal
1 голос
/ 01 марта 2011

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

Если вы хотите иметь простой способ создания анонимных делегатов и их подключенияиспользуя Reflection, вы можете написать очень простой класс:

class Closure {
  public Action Operation { get; set; }
  public void Invoke() { Operation(); }
}

Затем вы можете создать операцию, используя что-то вроде этого (и использовать Invoke в качестве целевого метода):

var op = new Closure { Operation = delegate() { .. } };

Это зависит от того, что именно вы пытаетесь сделать - смысл перехвата событий с помощью Reflection заключается в том, что у вас просто есть какой-то метод, который вы хотите запустить.Если у вас есть делегат (например, Action), вы можете использовать его напрямую.Подобный класс может быть полезен, если вы хотите создать неизвестный делегат во время компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...