Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The output of this code block doesn't make sense to me

The runtime type of all the calling instances is D hence, all the invocations of F() should be the F() method declared in D.

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

the output is:

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

Shouldn't the output be:

D.F
D.F
D.F
D.F
like image 464
Garrett Biermann Avatar asked Apr 08 '13 06:04

Garrett Biermann


2 Answers

Versioning with the Override and New Keywords (C# Programming Guide)

If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class.

So you'r F methods from A and B are not connected with these from C and D, and that's why you get what you get.

At runtime CLR looks for virtual method implementation that should be used starting from type the variables is declared to be up to type it really is. For a.F() and b.F() it stops on B.F() declaration, because C.F() is a different method (because of new).

like image 54
MarcinJuraszek Avatar answered Sep 21 '22 13:09

MarcinJuraszek


It should not...

A a = d;

This means you are creating a class of type A. And since you are explicitly overriding the related method in class B; A employs the method in the B class.

On the otherhand, in this line;

new public virtual void F() { Console.WriteLine("C.F"); }

You are declaring that you will not use the F() method from base by using the new keyword.

If you had overriden the F() method in D and C classes, all instance would have called the F() method declared in D class.

like image 33
daryal Avatar answered Sep 20 '22 13:09

daryal