1

Fist of all, I will use virtual and override

for example, base class A has method A.do(), inherited class B has B.do() which overrides A's.

if I call (B as A).do(), which do() would it execute?

or, if there is a method void mymethod(A a) {a.do()}, now I call it by B b; mymethod(b), would it execute b.do()?

colinfang
  • 20,909
  • 19
  • 90
  • 173

4 Answers4

3

The most top override method always will be called, i.e. b.Do() or (b as A).Do() or ((A)b).Do() will call B.Do().

I don't know a way how to call a base method from child class if child class overrides it.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
2
public class A
{
    public virtual void Do() { Console.Write("a"); }
    public void Do2() { Console.Write("a2"); }
}

public class B : A
{
    public override void Do() { Console.Write("b"); }
    public new void Do2() { Console.Write("b2"); }
}

class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        A a = b;
        b.Do();               //b
        ( b as A ).Do();      //b
        a.Do();               //b
        ( (A)b ).Do();        //b

        ( b as A ).Do2();     //a2
        ( (A)b ).Do2();       //a2
        ( b ).Do2();          //b2
    }
}  

Output:

b b b b
a2 a2 b2
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Nahum
  • 6,959
  • 12
  • 48
  • 69
  • 2
    Actaully it will call `B.Do()` as far as `B : A` – abatishchev Sep 18 '11 at 10:47
  • 1
    You sure about that? When you suggest someone running the code maybe you should run it first. – Darin Dimitrov Sep 18 '11 at 10:47
  • 1
    @Nahum, abatishchev is correct. The dynamic dispatch works no matter how is the reference you reached it through declared (-1). – Branko Dimitrijevic Sep 18 '11 at 10:51
  • 2
    There is nothing to be embarrassed of. The important thing is that you now actually tested the code and posted a correct answer. That's what brings value to the community. I have replaced my downvote with an upvote and hope others would do the same. – Darin Dimitrov Sep 18 '11 at 11:00
1

It entirely depends on whether the do() method was declared virtual or not. If it is not virtual then A.do() is called. If it is virtual then B.do() is called. It is the virtual keyword that enables polymorphism and allows calling a method independent of the type of the reference.

There is no mechanism in C# that allows directly calling a virtual A.do() method from a B object reference. The only exception is using base.do() inside an instance method of class B.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • yes i will reedit so make it clear i go the proper way of polymophism.. virtual + override – colinfang Sep 18 '11 at 10:55
  • If `A.Do()` is not virtual so `B.Do()` does not override it but hide (with the appropriate compiler warning) - then `B.Do()` anyway will be called, will it not? – abatishchev Sep 18 '11 at 10:55
  • @abat - no, A.Do() is called when the object reference is of type A, either explicitly or by casting. Try it :) – Hans Passant Sep 18 '11 at 11:01
1
public class A
{
    public A() { }
    public void Do() { Console.Write("A"); }

}

public class B : A
{
    public B() { }
    public void Do() { Console.Write("B");  }
}

class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        b.Do(); //<-- outputs B
        (b as A).Do(); //<-- outputs A
      }
}

compiler warns for hiding not overriding:

Warning 1 'ConsoleApplication5.B.Do()' hides inherited member 'ConsoleApplication5.A.Do()'. Use the new keyword if hiding was intended. c:\Program.cs 18 21 ConsoleApplication5

that is since you are not overriding anything, but simply hiding the method from A.

however

public class A
{
    public A() { }
    public virtual void Do() { Console.Write("A"); }

}

public class B : A
{
    public B() { }
    public  override void Do() { Console.Write("B");  }
}

calls B twice, when method is overridden.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Caspar Kleijne
  • 21,552
  • 13
  • 72
  • 102