Calling the overridden method from the base class in C#

Which method is called is determined via polymorphism on the type that is passed into the AnotherObject constructor:

AnotherObject a = new AnotherObject(new A()); // invokes A.MyMethod() 
AnotherObject b = new AnotherObject(new B()); // invokes B.MyMethod() 
AnotherObject c = new AnotherObject(new BaseClass()); //invokes BaseClass.MyMethod() 

Sorry, but you are completely mistaken; this would go against the entire point of virtual methods. If someObject is an A then A.MyMethod will be invoked. If someObject is a B then B.MyMethod will be invoked. If someObject is a BaseClass and not an instance of a type derived from BaseClass then BaseClass.MyMethod will be invoked.

Let's use everyone's favorite example:

class Animal {
    public virtual void Speak() {
        Console.WriteLine("i can haz cheezburger?");
    } 
}
class Feeder {
    public void Feed(Animal animal) { animal.Speak(); }
}
class Cat : Animal {
    public override void Speak() { Console.WriteLine("Meow!"); }
}
class Dog : Animal {
    public override void Speak() { Console.WriteLine("Woof!"); }
}

Then:

Animal a = new Animal();
Animal c = new Cat();
Animal d = new Dog();
Feeder f = new Feeder();
f.Feed(a);
f.Feed(c);
f.Feed(d);

This will print:

i can haz cheezburger?
Meow!
Woof!

Again, this is the entire point of virtual methods.

Further, we can go to the specification. From 10.6.3 (Virtual methods)

In a virtual method invocation, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke.

(Bolding and italics in original.)

In precise terms, when a method named N is invoked with an argument list A on an instance with a compile-time type C and a run-time type R (where R is either C or a class derived from C), the invocation is processed as follows:

• First, overload resolution is applied to C, N, and A, to select a specific method M from the set of methods declared in and inherited by C. This is described in §7.5.5.1.

• Then, if M is a non-virtual method, M is invoked.

Otherwise, M is a virtual method, and the most derived implementation of M with respect to R is invoked.

(Bolding not in original.)

Then, we need the definition of "most derived implementation of M." This is a nice recursive definition:

The most derived implementation of a virtual method M with respect to a class R is determined as follows:

• If R contains the introducing virtual declaration of M, then this is the most derived implementation of M.

• Otherwise, if R contains an override of M, then this is the most derived implementation of M.

• Otherwise, the most derived implementation of M with respect to R is the same as the most derived implementation of M with respect to the direct base class of R.

Thus, in our example above with Cat : Animal and Dog : Animal, when the parameter a to Feeder.Feed(Animal) is an instance of Cat then Cat.Speak is the most derived implementation. This is why we will see "Meow!" and not "i can haz cheezburger?"


If MyMethod() is abstract on the base class, then the version in the derived classes will be used. So if you don't need to call the instance in the base class, this would be an option.

    static void Main(string[] args)
    {

        A classA = new A();
        B classB = new B();

        DoFunctionInClass(classA);
        DoFunctionInClass(classB);
        DoFunctionInClass(classA as BaseClass);

        Console.ReadKey();
    }

    public static void DoFunctionInClass(BaseClass c) 
    {
        c.MyMethod();
    }



public abstract class BaseClass
{
    public abstract void MyMethod();
}


public class A : BaseClass
{
    public override void MyMethod()
    {
        Console.WriteLine("Class A");
    }
}

public class B : BaseClass
{
    public override void MyMethod()
    {
        Console.WriteLine("Class B");
    }
}