2017-08-24 33 views
2

我写一个基类和两个派生类:为什么调用这个虚拟方法?

class Base 
    { 
     public virtual void fn() 
     { 
      Console.WriteLine("base fn"); 
     } 
    } 

class Derived1 : Base 
    { 
     public override void fn() 
     { 
      Console.WriteLine("derived1 fn"); 
     } 
    } 

class Derived2 : Derived1 
    { 
     public new void fn() 
     { 
      Console.WriteLine("derived2 fn"); 
     } 
    } 

然后创建Derived2的的一个实例,由基底变量引用。然后调用fn()方法:

class Program 
    { 
     static void Main(string[] args) 
     { 
      Base b = new Derived2(); 
      b.fn(); 
      Console.Read(); 
     } 
    } 

结果是调用了Derived1类的fn()。

据我所知,如果调用虚拟方法,CLR将在运行时类型的方法表中寻找Derived2的方法;如果调用非虚方法,ClR将在变量类型Base的方法表中查找它。但为什么它会调用Derived1的方法?

答案“因为Derived1覆盖了基地的fn()”并不足以澄清我的难题。请给我更多的细节。

回答

2

虚拟方法调用进行了说明如在reference如下:

当调用虚拟方法,所述对象的运行时类型是 检查用于重写构件。 派生类中最高 的重写成员被称为,如果没有 派生类已重写成员,则该成员可能是原始成员。

由于Derived2的类隐藏使用一个“新”的关键字的基础方法,CLR将寻找在最派生类的重写构件,其为Derived1和执行它的方法。

+0

我做了另一个测试: –

相关问题