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

3

7

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
Mestee answered 8/4, 2013 at 6:15 Comment(1)
You should edit question title to much the problemForth
F
7

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).

Forth answered 8/4, 2013 at 6:21 Comment(0)
M
1

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.

Monogyny answered 8/4, 2013 at 6:23 Comment(0)
B
0

You are using new public virtual void F() in class C:B. It means that the F() in class C and the F() in class B are different method.

So when you override C to class D, the method F() in class D is overwritten from class C, not B.

Another obvious example can be like this:

  C c = new C();
  B b = c;
  b.F();
  c.F();
Basuto answered 8/4, 2013 at 6:20 Comment(4)
But the runtime type of all the calling instances is D, which means the implementation of F() in D is the one that's invoked.Mestee
Not exactly until the method F() is overridden. If you use new instead, it will be handled as a new method, not an overriddenBasuto
Got it! And because the closest implementation to the caller type at runtime, in this case the F() in B for a.F(); b.F(); and F() in D for c.F(); d.F();, is called.Mestee
True. Just consider that c.F() is a new method instead an inherited one.Basuto

© 2022 - 2024 — McMap. All rights reserved.