【问题标题】:Delegate.CreateDelegate() and generics: Error binding to target methodDelegate.CreateDelegate() 和泛型:错误绑定到目标方法
【发布时间】:2010-04-26 16:13:42
【问题描述】:

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

我正在尝试从 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 说错误绑定到目标方法。 :/

我做错了什么?

【问题讨论】:

    标签: c# .net generics exception delegates


    【解决方案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 创建了一个Delegateinstance,不知道它的类型参数就无法存在。因此,你不能绑定到classyDelegate,你需要知道实际涉及的类型。

    【讨论】:

    • 嗨,德里斯!谢谢您的答复。 “您不能声明方法签名的差异”是什么意思?
    • 他指的是泛型参数上的 outin 关键字。
    • 我的意思是你不能在类中的方法签名上使用 out 和 in 修饰符。您只能在委托和接口声明中使用它们。
    • 好的!我现在不明白。 ...更正...非常感谢您:) +1 +1
    • -1:正如documentation 解释的那样,Delegate.CreateDelegate(Type,MethodInfo) 重载也可以为实例方法创建委托。 (例如,可以使用CreateDelegate(typeof(Func&lt;Object, String&gt;), toStringMethodInfo)ToString() 创建一个委托,之后toStringDelegate(someObject) 将等效于someObject.ToString()。这称为“打开实例委托”,非常有用。跨度>
    猜你喜欢
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 2013-06-06
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    相关资源
    最近更新 更多