6

Can someone explain to me why is the overridden method being called when I cast the class into the base one:

    class Base
    {
        public virtual void VirtualMethod()
        {
            Console.WriteLine("Base virtual method");
        }
    }

    sealed class Derived : Base
    {
        public override void VirtualMethod()
        {
            Console.WriteLine("Overriden method");
        }
    }

    static void Main(String[] args)
    {
        Derived d = new Derived();
        ((Base)d).VirtualMethod();
    }

I mean this code prints:

Overriden method

and not

Base virtual method

Its a run-time or compile-time future?

I know i can call the Base's virtual method from the derived by calling base.VirtualMethod() but can I call it from outside? (like from Main or some other class)

Thanatos
  • 1,176
  • 8
  • 18
  • Please try to understand what @Jon Skeet has answered. He is completely right. The design reason is a few good decades of experience and head-banging against walls to find better and better ways to write code. The "under the hood"/mechanical reason is somehow irrelevant since all of languages and runtimes that support OOP have the same behavior (at least when it comes to virtual methods) and each one is implemented differently. About your second question please have a look at: http://stackoverflow.com/questions/437926/force-calling-the-base-method-from-outside-a-derived-class – Eduard Dumitru Feb 28 '13 at 16:49

2 Answers2

9

The method implementation is chosen based on the execution-time type of the object. That's a large part of the point of it. Anyone can use:

public void Foo(Base b)
{
    b.VirtualMethod();
}

... and not need to know or care what the execution type is, because polymorphism will take care of it.

I know i can call the Base's virtual method from the derived by calling base.VirtualMethod() but can I call it from outside?

No (at least, not without some horribly hackery to call the virtual method non-virtually), and that's a deliberate part of encapsulation. The overriding implementation has effectively replaced the original implementation for that object.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    +1. Note that behavior is opposite to C++ where virtual calls from constructor would call base class' implementation. Either behavior is confusing and can bring surprising side effects and thus generally calling virtual functions from constructor is not recommended. – Alexei Levenkov Feb 28 '13 at 16:52
2

If you want to access base implementation you should not use override, you should use new. Override overrides any parent implementation, new 'hides' the parent implementation so that you can access the implementation by casting as the parent object then invoking the method.

internal class Program
{
    private static void Main(string[] args)
    {
        Derived d = new Derived();
        d.VirtualMethod();
        ((Base) d).VirtualMethod();

        Console.ReadLine();
    }

    private class Base
    {
        public virtual void VirtualMethod()
        {
            Console.WriteLine("Base virtual method");
        }
    }

    private sealed class Derived : Base
    {
        public new void VirtualMethod()
        {
            Console.WriteLine("Overriden method");
        }
    }
}

This will output:

Overriden method
Base virtual method

Kacey
  • 89
  • 1
  • 6