Динамическое связывание в 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.
это означает, что C
public new virtual void WhoAreYou(){}
разрывает цепочку виртуальных методов.
когда вы вызываете метод WhoAreYou () из D по ссылке A. виртуальность начинает работать, но она ломается при C.