Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is base class method called instead of derived class method?

Tags:

c#

inheritance

Expecting "Hello from the derived." but getting "Hello from the base.".

class Program
{
    interface IBase
    {
        void Method();
    }

    public class Base: IBase
    {
        public virtual void Method()
        {
            Console.WriteLine("Hello from the base.");
        }
    }

    public class Derived : Base
    {
        public virtual new void Method()
        {
            Console.WriteLine("Hello from the derived.");
        }
    }

    static void Main(string[] args)
    {
        IBase x = new Derived();
        x.Method();
    }
}

So why isn't the derived class's method called. And more importantly, how can I get the derived classes method to get called without casting x to the Derived type?

In my actual application, IBase has several other related methods and Derived only replaces two of the methods in IBase.

like image 573
estimpson Avatar asked Nov 13 '12 15:11

estimpson


2 Answers

When you use the new modifier you are specifically saying that the method is not part of the virtual dispatch chain for that hierarchy, so calling the method by the same name in the base class will not result in redirection to the child class. If you mark the method with override instead of new then you will see the virtual dispatch that you are expecting to see.

You will also need to remove virtual from the derived class's method as you cannot mark an override method as virtual (it already is).

If you really don't want to override the method then it may be more appropriate, in your situation, to not use inheritance at all. You may simply want to use interfaces exclusively:

public interface IFoo
{
    void Foo();
}

public class A : IFoo
{
    public void Foo()
    {
        Console.WriteLine("I am A, hear me roar!");
    }
}

public class B : IFoo
{
    public void Foo()
    {
        Console.WriteLine("I am B, hear me roar!");
    }
}

private static void Main(string[] args)
{
    IFoo foo = new A();
    foo.Foo();

    foo = new B();
    foo.Foo();

    Console.WriteLine();
    Console.WriteLine("Press any key to exit . . .");
    Console.ReadKey(true);
}
like image 117
Servy Avatar answered Nov 05 '22 15:11

Servy


This is basic polymorphism at work.

For the behavior you're looking for, you would need to set your derived method to override the inherited method:

public class Derived : Base
{
    public override void Method()
    {
        Console.WriteLine("Hello from the derived.");
    }
}
like image 21
Jerad Rose Avatar answered Nov 05 '22 13:11

Jerad Rose