Динамическое связывание в C#

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" !!!!

Как ссылка выделяется внутриссылка A содержит ссылку на B? Кто-нибудь может объяснить, что происходит?

3 ответов


в классе C метод WhoAreYou() не переопределяет метод базового класса, так как он определен с new ключевое слово, которое добавляет новая метод то же самое имя скрывает метод базового класса. Вот почему это:

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

вызывает переопределенный метод в D, который переопределяет метод базового класса определен с new ключевое слово.

однако, когда целевой тип A, тогда это:

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

вызывает переопределенный метод в B, как вы вызываете метод на a типа A чей метод переопределяется B.


ваш метод класса C WhoAreYou() является "новым", и поэтому скрывает его от B. Это означает, что переопределение в классе D переопределяет метод C вместо B (который переопределяет A).

поскольку у вас есть ссылка на A, самая дальняя по иерархии функция WhoAreYou () - это функция класса B.

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


это означает, что C

public new virtual void WhoAreYou(){}

разрывает цепочку виртуальных методов.

когда вы вызываете метод WhoAreYou () из D по ссылке A. виртуальность начинает работать, но она ломается при C.