Reputation: 113
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.
Upvotes: 9
Views: 7688
Reputation: 203827
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);
}
Upvotes: 12
Reputation: 16628
The new'd Method in Derived only exists in a Derived instance, where it effectively hides the base implementation.
But IBase type only knows the Base's implementation, so it calls that.
To answer your question, to call the derived's implementation you'd do:
Derived d = new Derived();
d.Method();
((IBase)d).Method();
//Prints:
//Hello from the derived.
//Hello from the base.
Upvotes: -1
Reputation: 7773
Use the override keyword instead of virtual new
in your child class.
Therefore, your code should look like:
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 override void Method() // The magic happens here!
{
Console.WriteLine("Hello from the derived.");
}
}
static void Main(string[] args)
{
IBase x = new Derived();
x.Method();
}
}
As described here, the new
keyword is used to hide the parent method, which is not what you're looking for.
Upvotes: 2
Reputation: 21485
new
keyword creates a new method and says that the base method is hidden. But it is only for consumers of your derived class, since the base class code does not know anything about it.
override
keyword overrides the base class implementation with a new one.
class Program
{
interface IBase
{
void Method();
}
public class Base: IBase
{
public virtual void Method()
{
Console.WriteLine("Hello from the base.");
}
}
public class Derived : Base
{
// the next line was changed.
public override void Method()
{
Console.WriteLine("Hello from the derived.");
// note that if you want to call the original implementation, you do it like this:
base.Method();
}
}
static void Main(string[] args)
{
Base x = new Derived();
x.Method();
}
}
Upvotes: 1
Reputation: 15503
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.");
}
}
Upvotes: 3