Need to understand the below code for C# virtual methods
Asked Answered
A

4

6

this is a small code which shows virtual methods.

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;        

    a.F();
    b.F();        
 }
}

This code is printing the below output:

B.F
B.F

I can not understand why a.F() will print B.F ?

I thought it will print D.F because Class B overrides the F() of Class A, then this method is being hidden in Class C using the "new" keyword, then it's again being overridden in Class D. So finally D.F stays.

but it's not doing that. Could you please explain why it is printing B.F?

Arquit answered 6/7, 2012 at 5:26 Comment(0)
T
5
A a = d;
a.F();

It will find F() as follows.

  1. First in class A
  2. Then in class B
  3. Then in class C
  4. Then in class D

Now F() will be found in A, and B. Thus B.F() will be invoked. In class C F() is different (as it is new implementation and does not override from A/B). So In 3rd step, c.F() will not be found. In Class D, it overrides new function created by C, thus it will also not be found.

Due to new keyword, the resulting code is like following (with respect to virtual override)

    class A
    {
        public virtual void F() { Console.WriteLine("A.F"); }
    }
    class B: A
    {
        public override void F() { Console.WriteLine("B.F"); }
    }
    class C: B
    {
        public virtual void F1() { Console.WriteLine("C.F"); }
    }
    class D: C
    {
        public override void F1() { Console.WriteLine("D.F"); }
    }
Treadmill answered 6/7, 2012 at 5:36 Comment(1)
Thank you Tilak and everyone, I got it now :-)Arquit
V
2

Unlike method overriding, which allows polymorphism, hiding a method using the new keyword is just a matter of naming (and note that using new simply removes the warning that you are hiding something).

In class C, when you declare:

new public virtual void F() { ... }

Here you're defining a brand new method unrelated to the superclass's F(), which happens to have the same name.

When an instance of F is assigned to variable of type A or B, calling F() using those variables points to the method defined by the superclass.

Imagine if you hadn't called C's method F() but something different like G(). The following code wouldn't compile:

a.G();
b.G();

Since with variables statically typed as A or B, the compiler can't see the newly declared method. It's the same situation in your example, except the superclass happens to have the original method named F() to call instead.

Vedi answered 6/7, 2012 at 5:33 Comment(0)
E
1

A.F is overridden by B.F. Therefore when A.F is called, it will execute B.F. B.F is 'connected' to 'A.F'.

Now C.F hides B.F with the new keyword. C.F is not connected to B.F/A.F. When you create C, and call F(), it will execute C.F. If you cast C to either type A or B, and call F, it will execute B.F, since B.F and A.F are connected.

C.F is overridden by D.F. They are connected. When C.F or D.F is called, it will execute D.F. Now when you cast object D to either A or B, and call F(), it will call B.F.

Hope this helps to make it clearer.

Erythromycin answered 6/7, 2012 at 5:35 Comment(0)
T
0

As others already pointed out, the new keyword in C hides the overload of F, therefor no suiting overload of F is found in C or D.

If you need more detailed information on C# finding the right overload, please read those two:

Jon Skeet: C# in Depth, chapter Overloading

Visual Studio 2010: Breaking changes, here: overload resolution

Tore answered 6/7, 2012 at 5:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.