Delegate.CreateDelegate()和泛型:绑定到目标方法的错误

SDR*_*yes 9 .net c# generics delegates exception

我在使用反射和泛型创建委托集合时遇到问题.

我正在尝试从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...
}
Run Code Online (Sandbox Code Playgroud)

和仿制药烹饪:

// 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( );
Run Code Online (Sandbox Code Playgroud)

但是Delegate.CreateDelegate( delegateType, method )抛出一个ArgumentException,说Error绑定到target方法.:/

我究竟做错了什么?

dri*_*iis 16

这是因为Delegate.CreateDelegate的重载仅支持创建指向静态方法的委托.如果要绑定到实例方法,还需要传入创建的委托应该调用该方法的实例.

你可能想要:

from method in typeof( Classy ).GetMethods( BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic )
let delegateType = typeof( classyDelegate<,> )
select Delegate.CreateDelegate( delegateType, yourInstance, method )
Run Code Online (Sandbox Code Playgroud)

此外,您的代码示例将无法编译.您不能在方法签名上声明差异; 并且你不能在非抽象类中省略实现.

最后,Delegate.CreateDelegate创建一个Delegate 实例,如果不知道它的类型参数,它就不能存在.因此,您无法绑定到classyDelegate <,>,您需要知道所涉及的实际类型.

  • 他的泛型参数表示`out`和`in`关键字. (3认同)
  • -1:正如[文档](http://msdn.microsoft.com/en-us/library/53cz7sc6.aspx)所解释的那样,`Delegate.CreateDelegate(Type,MethodInfo)`重载也可以为实例方法创建委托.(例如,可以使用`CreateDelegate(typeof(Func <Object,String>),toStringMethodInfo)`为`ToString()`创建一个委托,之后`toStringDelegate(someObject)`将等同于`someObject.ToString ()`.这被称为"开放实例委托",它非常有用. (2认同)