.NET 4如何决定在使用'dynamic'(c#)的子类

本文关键字:子类 dynamic 何决定 NET 决定 | 更新日期: 2023-09-27 18:16:45

我有这样的代码片段:

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();
    }
}

输出为:
一个
B

我试图理解为什么,当使用动态作为变量v2的类型时,B.Method()被调用。我知道,由于B.Method()是使用new声明的,它是一个不同于a . method()的方法,它只是具有相同的签名。如果我将变量v2声明为B(并进行强制类型转换),代码将按照我的预期,打印出B。

那么为什么动态使。net将v2视为B而不是a呢?

谢谢!

.NET 4如何决定在使用'dynamic'(c#)的子类

提示v2应被视为A而不是B的唯一可用信息是v1的编译时类型。当你将v1赋值给v2时,你是在要求运行时丢弃所有在编译时可能知道的关于v2的信息,并在运行时找出Method在运行时引用的是什么,除了对象本身,没有其他信息,它的运行时类型是B

当提供带有非虚拟隐藏方法的运行时类时,运行时绑定器可以选择使用派生最少的类,而不是派生最多的类。使用最衍生的一个符合该类型的"自然"用法;这是相同的方法,你得到与var v3 = new B(); v3.Method();

尽管您声明v1为类型A,但您将其赋值为new B()。当你把对象实例赋值给动态v2时,你是在给这个变量赋值一个B类型的内存对象,所以它仍然会表现为"B"。如果你想访问基方法,你必须强制转换,例如((A)v2)。method ();