C# 语言特性系列(4) 深入理解虚方法

The implementation of a non-virtual method is invariant: The implementation is the same whether the method is invoked on an instance of the class in which it is declared or an instance of a derived class. In contrast, the implementation of a virtual method can be superseded by derived classes. The process of superseding the implementation of an inherited virtual method is known as overriding that method.

In a virtual method invocation, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke. In a non-virtual method invocation, the compile-time type of the instance is the determining factor. In precise terms, when a method named N is invoked with an argument list A on an instance with a compile-time type C and a run-time type R (where R is either C or a class derived from C), the invocation is processed as follows:

  • First, overload resolution is applied to C, N, and A, to select a specific method M from the set of methods declared in and inherited by C.
  • Then, if M is a non-virtual method, M is invoked.
  • Otherwise, M is a virtual method, and the most derived implementation of M with respect to R is invoked.

For every virtual method declared in or inherited by a class, there exists a most derived implementation of the method with respect to that class. The most derived implementation of a virtual method M with respect to a class R is determined as follows:

  • If R contains the introducing virtual declaration of M, then this is the most derived implementation of M.
  • Otherwise, if R contains an override of M, then this is the most derived implementation of M.
  • Otherwise, the most derived implementation of M with respect to R is the same as the most derived implementation of M with respect to the direct base class of R.

using System;
class A
{
   public void F() { Console.WriteLine("A.F"); }
   public virtual void G() { Console.WriteLine("A.G"); }
}
class B: A
{
   new public void F() { Console.WriteLine("B.F"); }
   public override void G() { Console.WriteLine("B.G"); }
}
class Test
{
   static void Main() {
      B b = new B();
      A a = b;
      a.F();
      b.F();
      a.G();
      b.G();
   }
}


A.F
B.F
B.G
B.G

Notice that the statement a.G() invokes B.G, not A.G. This is because the run-time type of the instance (which is B), not the compile-time type of the instance (which is A), determines the actual method implementation to invoke.

using System;
class A
{
   public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
   public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
   new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
   public override void F() { Console.WriteLine("D.F"); }
}
class Test
{
   static void Main() {
      D d = new D();
      A a = d;
      B b = d;
      C c = d;
      a.F();
      b.F();
      c.F();
      d.F();
   }
}


B.F
B.F
D.F
D.F

 


 

[我Case1]

 

 1  class A
 2     {
 3         public virtual void F() { Console.WriteLine("A.F"); }
 4     }
 5     class B : A
 6     {
 7         public override void F() { Console.WriteLine("B.F"); }
 8     }
 9     class C : B
10     {
11          public override void F() { Console.WriteLine("C.F"); }
12     }
13     class D : C
14     {
15         public override void F() { Console.WriteLine("D.F"); }
16     }
17     class Test
18     {
19         static void Main()
20         {
21             D d = new D();
22             A a = d;
23             B b = d;
24             C c = d;
25             a.F();
26             b.F();
27             c.F();
28             d.F();
29         }
30     }

 

Result: D.F

[我Case2]

 1  class A
 2     {
 3         public virtual void F() { Console.WriteLine("A.F"); }
 4     }
 5     class B : A
 6     {
 7         public override void F() { Console.WriteLine("B.F"); }
 8     }
 9     class C : B
10     {
11         //public override void F() { Console.WriteLine("C.F"); }
12     }
13     class D : C
14     {
15         //public override void F() { Console.WriteLine("D.F"); }
16     }
17     class Test
18     {
19         static void Main()
20         {
21             C c = new C();
22             A a = c;
23             B b = c;
24             //C c = d;
25             a.F();
26             b.F();
27             //c.F();
28             //d.F();
29     
30         }
31     }
32 

Result: ?

http://msdn.microsoft.com/en-us/library/aa645767(VS.71).aspx

posted @ 2008-07-10 10:57  许晓光  阅读(288)  评论(0编辑  收藏  举报