Delegate.CreateDelegate() и generics: Ошибка привязки к целевому методу
У меня проблемы с созданием коллекции делегатов с использованием рефлексии и обобщений.
Я пытаюсь создать коллекцию делегатов из методов Ally, у которых есть общая сигнатура метода.
public class Classy
{
public string FirstMethod<T1, T2>( string id, Func<T1, int, IEnumerable<T2>> del );
public string SecondMethod<T1, T2>( string id, Func<T1, int, IEnumerable<T2>> del );
public string ThirdMethod<T1, T2>( string id, Func<T1, int, IEnumerable<T2>> del );
// And so on...
}
И дженерики приготовления:
// This is the Classy's shared method signature
public delegate string classyDelegate<out T1, in T2>( string id, Func<T1, int, IEnumerable<T2>> filter );
// And the linq-way to get the collection of delegates from Classy
(
from method in typeof( Classy ).GetMethods( BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic )
let delegateType = typeof( classyDelegate<,> )
select Delegate.CreateDelegate( delegateType, method )
).ToList( );
Но Delegate.CreateDelegate( delegateType, method )
генерирует ArgumentException, говорящее об ошибке привязки к целевому методу.: /
Что я делаю неправильно?
1 ответ
Это связано с тем, что перегрузка Delegate.CreateDelegate поддерживает только создание делегатов, указывающих на статические методы. Если вы хотите привязать методы экземпляра, вам также нужно передать экземпляр, в котором ваш созданный делегат должен вызвать метод.
Вы, вероятно, хотите:
from method in typeof( Classy ).GetMethods( BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic )
let delegateType = typeof( classyDelegate<,> )
select Delegate.CreateDelegate( delegateType, yourInstance, method )
Кроме того, ваш пример кода не будет компилироваться. Вы не можете объявить отклонение в сигнатурах методов; и вы не можете опустить реализацию в неабстрактном классе.
Наконец, Delegate.CreateDelegate создает экземпляр Delegate, который не может существовать, не зная его параметров типа. Следовательно, вы не можете связываться с classyDelegate<,>, вам нужно знать, какие именно типы задействованы.