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

参照が内部的にどのように割り当てられているか、参照 A には B の参照が含まれていますか? 何が起こっているのか説明できる人はいますか?

4

3 に答える 3

7

classCでは、基本クラスのメソッドを非表示にする同じ名前の新しいメソッドを追加するキーワードで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メソッドを呼び出しているため、 でオーバーライドされたメソッドを呼び出します。aAB

于 2012-06-01T16:00:26.433 に答える
3

クラス C の WhoAreYou() メソッドは「新しい」ため、B からメソッドを非表示にします。つまり、クラス D のオーバーライドは、B のメソッドではなく C のメソッドをオーバーライドしています (A のメソッドをオーバーライドしています)。

A への参照があるため、その WhoAreYou() 関数の階層の最も下にあるのは、クラス B のものです。

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

于 2012-06-01T16:00:13.100 に答える
1

それは意味です、それはCの

public new virtual void WhoAreYou(){}

仮想メソッドの連鎖を断ち切ります。

Aの参照でDのWhoAreYou()メソッドを呼び出すと仮想化が動き出すが、Cで壊れる。

于 2012-06-01T18:24:22.810 に答える