10
class A 
 {
   public virtual void WhoAreYou() { Console.WriteLine("I am an A"); }
 }
class B : A
{
  public override void WhoAreYou() { Console.WriteLine("I am a B"); }
}
class C : B
{
 public new virtual void WhoAreYou() { Console.WriteLine("I am a C"); }
}
class D : C 
{
  public override void WhoAreYou() { Console.WriteLine("I am a D"); }
}


C c = new D();
c.WhoAreYou();// "I am a D"
A a = new D();
a.WhoAreYou();// "I am a B" !!!!

How the reference is allocated internally,reference A contains the reference of B? Can any one explain Whats going On?

C-va
  • 2,910
  • 4
  • 27
  • 42
  • Um I might be wrong but I think this is what's happening. When you declare an object of class D and assign it to a class C --- class C has a virtual function and in that case it will just use D's overwrite function. But when you declare an object of class D and assign it to a class A what happens is because D inherits from C and C from B and B finally inherits from A but at the same time overwrites A then you have that print statement. – Florin Stingaciu Jun 01 '12 at 15:56
  • how about: reading the msdn and trying to understand the virtual/override/new-machine? your example is totally clear! –  Jun 01 '12 at 15:59
  • @Flo: In first case the object C has the reference of D it calls D's method. But in Second case obviously A has the reference of D, while method invoke how it invoke B's method (what happen internally).. Quiet Confusing.. – C-va Jun 01 '12 at 16:04
  • Does `new virtual` even make sense conceptually, what is your intended result? – Matthew Jun 01 '12 at 16:27
  • @Matthew : Obviously hide the base class implementation and let the derived to override. – C-va Jun 01 '12 at 17:39
  • @MSDK It would do that without the `new` keyword. – Matthew Jun 01 '12 at 17:52
  • @Matthew: But Compiler throw warning if i let the method with virtual alone. – C-va Jun 02 '12 at 05:51
  • @MSK Not if you have it `override` – Matthew Jun 02 '12 at 15:47
  • @Matthew: Ya right. But if i put override it will invoke D's method,Obviously the last one in override hierarchy. – C-va Jun 02 '12 at 16:18
  • @MSK not if you instanciate a `new C()`. – Matthew Jun 02 '12 at 16:20
  • @Matthew : Ur right. But my point for this case : A a = new D(); a.WhoAreYou(); – C-va Jun 02 '12 at 16:38

3 Answers3

7

In class C, the method WhoAreYou() doesn't override the base class method, as it is defined with new keyword which adds a new method with the same name which hides the base class method. That is why this:

C c = new D();
c.WhoAreYou();// "I am a D"

invokes the overridden method in D which overrides its base class method defined with new keyword.

However, when the target type is A, then this:

A a = new D();
a.WhoAreYou();// "I am a B" !!!!

invokes the overridden method in B, as you're calling the method on a of type A whose method is overriden by B.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Thanks for the reply Nawaz. A has the reference of D, A doesnt know about its child classes. So, I have to track from derived one. Is it so? If not means .. But it will be better if how the reference of D call B's method and how it tracks the derived classes from A (in the aspect of method tables) like internal stuff.. – C-va Jun 02 '12 at 06:10
3

Your class C WhoAreYou() method is 'new', and therefor hiding the one from B. That means that the override in class D is overriding C's method instead of B's (which is overriding A's).

Since you have a reference to an A, the furthest down the hierarchy of it's WhoAreYou() function is the one in class B.

http://msdn.microsoft.com/en-us/library/435f1dw2.aspx

DLH
  • 146
  • 6
1

It is mean, that the C's

public new virtual void WhoAreYou(){}

breaks the chain of virtual methods.

When you call the method WhoAreYou() of D by reference of A. The virtuality starts work, but it breaks at C.

Hamlet Hakobyan
  • 32,965
  • 6
  • 52
  • 68