【问题标题】:Is it a bug that Delegate.CreateDelegate cannot bind to struct member overrides?Delegate.CreateDelegate 无法绑定到结构成员覆盖是一个错误吗?
【发布时间】:2011-05-18 15:32:05
【问题描述】:

按照这个答案后,我发现我必须使用ref 参数来调用结构上的实例方法。 How can I create an open Delegate from a struct's instance method?

我似乎无法绑定到显式接口实现之类的方法覆盖(以避免相关的装箱惩罚,(就 IL 而言,这实际上是覆盖)), 这是一个错误报告,说在 .NET 的未来版本中,我们可以绑定到结构上的接口成员: https://connect.microsoft.com/VisualStudio/feedback/details/574959/cannot-create-open-instance-delegate-for-value-types-methods-which-implement-an-interface?wa=wsignin1.0#details

但即使尝试绑定到 EqualsGetHashCodeToString 这样的成员也会导致错误 例如

public struct A
{
     public override int GetHashCode(){/*implementation goes here*/}
}
delegate TRet FuncByRef<TStruct,TRet>(ref TStruct) where TStruct:struct

...

Delegate.CreateDelegate(typeof(FuncByRef<A,int>),typeof(A).GetMethod("GetHashCode"));

将失败,并出现“错误绑定到目标方法”异常。

【问题讨论】:

  • 重新拳击开销/虚拟;请注意,接口处理仅适用于受约束的操作码,通常通过通用约束。虚拟方法的处理取决于它是否被覆盖(然后它可以使用静态调用)或没有(虚拟调用)。
  • @Marc Gravell,我不确定这是否正确,例如,我可以在表达式树中调用Int32.ToInt64(null),并且似乎没有任何拳击。由于该方法的执行速度比我首先将其转换为 IConvertible

标签: c# delegates


【解决方案1】:

让编译器担心怎么样,即

public static string SomeHelper(A obj) {
    return obj.SomeMethod();
}

然后改为绑定到“SomeHelper”。这也可能是需要的通用方法,它将使用神奇的“受约束”操作码。

这也类似于

Func<A string> func = obj => obj.SomeMethod();

如果您使用反射来获取方法,您可以尝试 DynamicMethod。

【讨论】:

  • 虽然我当然可以自己创建间接寻址,但我想知道为什么辅助方法无法解决这个问题。我当然可以编写一个动态方法来调用 by-ref int 参数它是 GetHashCode 方法,但为什么我不能使用应该处理这些东西的内置方法?
  • @MichaelB - 你知道吗?
  • 是的,升级到更高版本的 .net,即 4.5 解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 2020-03-11
  • 1970-01-01
相关资源
最近更新 更多