Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to understand the below code for C# virtual methods

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?

like image 658
Manas Saha Avatar asked Jul 06 '12 05:07

Manas Saha


People also ask

What is C used to code?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...


2 Answers

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"); }
    }
like image 81
Tilak Avatar answered Nov 02 '22 15:11

Tilak


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.

like image 34
Paul Bellora Avatar answered Nov 02 '22 16:11

Paul Bellora