当使用带有子类的“动态”(C#)时,.NET 4如何决定调用哪个方法?

时间:2016-11-07 16:18:23

标签: c# .net dynamic clr

我在这里有这段代码:

class A
{
    public void Method()
    {
        Console.WriteLine("A");
    }
}

class B: A
{
    public new void Method()
    {
        Console.WriteLine("B");
    }
}
class Program
{
    static void Main(string[] args)
    {
        A v1 = new B();
        v1.Method();

        dynamic v2 = v1;
        v2.Method();

        Console.ReadKey();
    }
}

输出结果为:
    一个
    乙

我试图理解为什么当使用dynamic作为变量v2的类型时,会调用B.Method()。我知道,因为B.Method()是使用 new 声明的,所以它与A.Method()不同,它只有相同的签名。如果我将变量v2声明为B(并进行强制转换),则代码执行我的预期,打印出B。

为什么动态使.NET将v2视为B而不是A?

谢谢!

2 个答案:

答案 0 :(得分:2)

唯一可用的信息提示v2应被视为A而不是B的编译时类型为v1。当您将v1分配给v2时,您要求运行时放弃在编译时可能已知的有关v2的所有内容并找出Method的内容在运行时,除了对象本身之外没有其他信息,其对象的运行时类型为B

当提供具有非虚拟隐藏方法的运行时类时,运行时绑定程序可能已选择使用派生最少的派生程序而不是派生程度最大的派生程序。使用最衍生的一个适合"自然"使用类型;它与var v3 = new B(); v3.Method();获得的方法相同。

答案 1 :(得分:1)

即使您将v1声明为类型A,您也将其指定为新的B()。当您将该对象实例分配给动态v2时,您正在为该变量分配类型B的内存对象,因此它仍将表现为" B"。如果您想访问基本方法,则必须进行转换,例如((A)V2)。方法();