Delegate.CreateDelegate () и generics: Ошибка привязки к целевому методу - PullRequest
9 голосов
/ 26 апреля 2010

У меня проблемы с созданием коллекции делегатов с использованием рефлексии и обобщений.

Я пытаюсь создать коллекцию делегатов из методов 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 Ответ

16 голосов
/ 26 апреля 2010

Это происходит потому, что перегрузка 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 создает делегат экземпляр , который не может существовать, не зная его параметров типа. Следовательно, вы не можете связываться с classyDelegate <,>, вам нужно знать фактические типы.

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