【问题标题】:Why does dynamic binding fail when using interface inheritance?为什么使用接口继承时动态绑定会失败?
【发布时间】:2012-03-10 17:47:37
【问题描述】:

在 C# 中,有人知道为什么我不能执行以下操作吗? (特别是下面标有“不好!”的行)

interface A
{
    void Add(dynamic entity);
}

interface B : A {}

class C : B
{
    public void Add(dynamic entity)
    {
        System.Console.WriteLine(entity);
    }
}

class Program
{
    static void Main(string[] args)
    {
        B b = new C();
        dynamic x = 23;
        b.Add(23);        // fine
        b.Add((int)x);    // fine
        (b as A).Add(x);  // fine
        //b.Add(x);       // NOT fine!
    }
}

如果调用不是动态绑定的,或者如果我明确地转换到层次结构根部的接口,我绝对没有问题,但是动态绑定调用给了我:

Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: No overload for method 'Add' takes '1' arguments
   at CallSite.Target(Closure , CallSite , B , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
   at Program.Main(String[] args) in C:\Users\Stuart\Documents\Visual Studio 2010\Projects\CSharp Testbed\Program.cs:line 218

【问题讨论】:

  • 顺便说一句,即使没有钻石继承,最后一次调用也会失败。
  • @YuriyGuts:一个最小的可编译示例就这么多吧? :) 好的,在这种情况下简化问题。
  • +1 - 请注意b.Add((int)x) 有效。
  • 这可能是因为性能问题。如果可能的话,运行时应始终检查由classinterface 实现的所有接口,以查看是否有更好的调用匹配。通常大部分工作将在编译期间完成。
  • 在 Microsoft Connect 上查看它已作为错误提交 - Dynamic runtime fails to find method from a base interface during runtime

标签: c# c#-4.0 inheritance dynamic interface


【解决方案1】:

在 Microsoft Connect 上查看它已作为错误提交 - Dynamic runtime fails to find method from a base interface during runtime

【讨论】:

    【解决方案2】:

    看起来多层接口继承是在传递动态类型变量时进行的。它肯定会破坏运行时绑定。

    此时,如果您想让它工作,一个可能的解决方法是:

    dynamic x = 23;
    b.Add((object)x);
    
    dynamic y = "Hello, World!";
    b.Add((object)y);
    

    由于动态被 IL 视为对象,因此将所有内容显式转换为类型 object 将使它为您工作。

    【讨论】:

    • 对于中间代码,动态类型实际上只是被视为类型对象。因此,至少在这种情况下,将动态转换为类型对象,因为两者在功能上等同于 OP 尝试执行的操作。
    • 问题不在于如何让它发挥作用,而在于为什么它不起作用
    • @oleksii:虽然我最初对此感到惊讶,但它似乎确实有效(即使我更改 C.Add 以使用 entity 做一些更有趣的事情)。我的理解是转换为object 强制绑定在编译时完成,但在函数entity 内仍然是动态类型的。所以这是使调用静态绑定的另一种方法-> 我说“我绝对没有问题”的情况。不幸的是,它仍然没有解释为什么我在动态绑定案例中遇到问题。
    • @BradRem:感谢您提供额外的解决方法。不过,我仍然很好奇问题出在哪里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 2011-05-27
    相关资源
    最近更新 更多