Executing a method override and method hide thread

I got confused in 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 get output like this

BBDD

Why is the inherited method called instead of the method in the declared type and why is the method in class D not called every time?

+4
source share
3 answers

I try to explain it differently.

virtual / override means that you implement / modify the behavior of the same method. This is an implementation of polymorphism . With new you create a completely new method. This has the same signature as the other method, but has nothing to do with it.

When calling these methods, it depends on what type of reference it has (type of compilation time) to select the method that you are actually calling.

Your code is equivalent to:

 public class A { public virtual string SomeMethod() { return "A"; } } public class B : A { public override string SomeMethod() { return "B"; } } public class C : B { public virtual string AnotherMethod() { return "C"; } } public class D : C { public override string AnotherMethod() { return "D"; } } 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.AnotherMethod()); //The method in class D is being called Console.WriteLine(d.AnotherMethod()); //The method in class D is being called } 

The compiler selects a call to the AnotherMethod method for a reference of type C (and D).

+3
source

When you call SomeMethod on instance A (i.e. A foo = new <A or derived>() ), you expect to get the most derived version of SomeMethod . This is the whole point of inheritance. Your code only needs to deal with instances of the base class, but if these instances really have a derived class, a special hidden implementation is called. This is the behavior that you get when you override a method.

This explains common scenarios such as

 A b = new B(); b.SomeMethod(); // B implementation invoked 

With new you do not override the method, you declare a new method with the same name. This method exists only for the class that declared it and its children, it is not part of the base classes and their inheritance chain.

So what does A a = new D(); a.SomeMethod(); A a = new D(); a.SomeMethod(); ? The variable is declared as A , therefore any methods / properties / etc displayed against it must be defined on A C defined a new SomeMethod method (and D overrides it), but this method does not exist on A , so it cannot be called here. The most derived implementation of SomeMethod (as indicated by type A ) is in B , so this is the implementation that is invoked.

The same story for B b = new D(); b.SomeMethod(); B b = new D(); b.SomeMethod();

This is only when we get to C c = new D(); c.SomeMethod() C c = new D(); c.SomeMethod() so that the new method has the ability to execute. This is because the variable is C , and therefore the new SomeMethod method is first declared in the variable type. And, as stated above, the most derivative possible version is called, which in this case means that the version is overridden by D

And I hope that we are all on the same page for D d = new D(); d.SomeMethod() D d = new D(); d.SomeMethod() :)

Others posted good links. Here is another thread that might help: C # and the hide method

And the last example shows an even stranger scenario when the "new" method is declared as private, so the next fogged type inherits the base version of the method, and does not inherit the "new" version. http://msdn.microsoft.com/en-us/library/aa691135

+4
source

This is a well-known behavior: when you hide a method (with new ), it is called only when you access it through an instance of the type of hide; when you use an instance of a base class, the original method is used.

Hiding does not override.

+2
source

All Articles