public class A
    {
       
        public  virtual void Func()
        {
            Console.WriteLine("Func In A");
        }    }
    class B : A
    {
        public virtual void Func()
        {
            Console.WriteLine("Func In B");
        }    }
    class C : B
    {
        public override void Func()
        {
            Console.WriteLine("Func In C");
        }
         
    }
执行代码如下:
   A c = new C();
   c.Func();
输出结果为:Func In A
为什么不是Func In C(难道C中方法不能重写A中虚方法吗?)编译器如何检查虚方法并执行相应的重写方法的呢?

解决方案 »

  1.   

    C是重写的B中的Func;
    而B并没有重写A;
    最后调用的是A的方法
      

  2.   


    那为什么把B中方法改为public override void Func()以后执行结果为Func In C
      

  3.   

    如果把B改为public override void Func()以后,就变成了C重写了B,B重写了A,传递一下,就是调用C中的方法了
      

  4.   


    C重写B?但是B中没有指定虚方法啊?难道是继承自A,但是A中的方法不是被B的方法给覆盖了吗?我又试了下把B中方法去掉,结果为Func In C ,请你解释下原因。最好把编译器选择某个方法的流程说下,谢谢。
      

  5.   

    1、当调用一个对象的函数时,系统会直接去检查这个对象申明定义的类,即申明类,看所调用的函数是否为虚函数;2、如果不是虚函数,那么它就直接执行该函数。而如果有virtual关键字,也就是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是转去检查对象的实例类。3、在这个实例类里,他会检查这个实例类的定义中是否有重新实现该虚函数(通过override关键字),如果是有,那么OK,它就不会再找了,而马上执行该实例类中的这个重新实现的函数。而如果没有的话,系统就会不停地往上找实例类的父类,并对父类重复刚才在实例类里的检查,直到找到第一个重载了该虚函数的父类为止,然后执行该父类里重载后的函数。如果B用public virtual void Func()
    则把A中的FunC给隐藏了,所以对C来说,A中的方法是不可见的,也就不存在重写了,所以会调用A中的方法
      

  6.   


    因为B并没有重写A的FuncC方法,那么B实际上有两个FunC,一个是符合A规格接口的,另一个是符合B规格接口的,一共有两个。
      

  7.   

    基本上在我们的系统中严禁这样写代码。这个例子是一个恶劣的.net编程机制的例子,应该注意。
      

  8.   

    我又找了找相关资料,发现这篇文章解释的还是不错的http://blog.163.com/hulei_accp/blog/static/106898640201132144013836/