I'm confused with the following scenario, we have a set of classes like this
public class A
{
public virtual string SomeMethod()
{
return "A";
}
}
public class B : A
{
public override string SomeMethod()
{
return "B";
}
}
public class C : B
{
public new virtual string SomeMethod()
{
return "C";
}
}
public class D : C
{
public override string SomeMethod()
{
return "D";
}
}
When i call the following method
private void Test()
{
A a = new D();
B b = new D();
C c = new D();
D d = new D();
Console.WriteLine(a.SomeMethod()); //The method in class B is being called
Console.WriteLine(b.SomeMethod()); //The method in class B is being called
Console.WriteLine(c.SomeMethod()); //The method in class D is being called
Console.WriteLine(d.SomeMethod()); //The method in class D is being called
}
I'm getting the output like this
B B D D
Why is it that the inherited method is being called, instead of the method in the declared type, and why isn't the method in class D
being called every time?
When you call SomeMethod
on an instance of A
(i.e. A foo = new <A or derived>()
), you expect to get the most derived version of SomeMethod
available. That's the whole point of inheritance. Your code only needs to deal with instances of the base class, but if those instances happen to really be of a derived class, the special dervied implementations are invoked. This is the behavior you get when you override a method.
This explains common scenarios like
A b = new B();
b.SomeMethod(); // B's implementation invoked
With new
, you are not overriding the method, you are declaring a brand new method with the same name. This method exists only on the class that declared it and its children, it's not part of the base classes and their inheritance chain.
So what does A a = new D(); a.SomeMethod();
do? The variable is declared as A
, so any methods/properties/etc invoked against it have to be defined on A
. C
defined a new method SomeMethod
(and D
overrides it), but this method doesn't exist on A
, so it cannot be invoked here. The most derived implementation of SomeMethod
(as declared on type A
) is in B
, so this is the implementation which is invoked.
Same story for B b = new D(); b.SomeMethod();
It's only when we get to C c = new D(); c.SomeMethod()
that the new method has a chance to execute. This is because the variable is a C
, and thus the new method SomeMethod
is for the first time declared on the variable type. And as stated above, the most derived possible version will be invoked, which in this case means the version overriden by D
.
And I hope we are all on the same page for D d = new D(); d.SomeMethod()
:)
Others have posted good links. Here's another thread that might help: C# and method hiding
And the last example here shows an even weirder scenario where the "new" method is declared as private, thus a further dervied type actually inherits the base version of the method, rather than inheriting the "new" version. http://msdn.microsoft.com/en-us/library/aa691135
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With