我在使用反射和泛型创建委托集合时遇到了问题。
我正在尝试从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,说错误绑定到目标方法。 :/
我做错了什么?
答案 0 :(得分: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 )
此外,您的代码示例将无法编译。您不能在方法签名上声明差异;并且你不能在非抽象类中省略实现。
最后,Delegate.CreateDelegate创建了一个Delegate 实例,如果不知道它的类型参数就不能存在。因此,您无法绑定到classyDelegate&lt;,&gt ;,您需要知道所涉及的实际类型。