0

私はvirtualメソッドに関するドキュメントを読んでいます:

仮想メソッド呼び出しでは、その呼び出しが行われるインスタンスの実行時型によって、呼び出す実際のメソッド実装が決まります。非仮想メソッドの呼び出しでは、インスタンスのコンパイル時のタイプが決定要因になります。正確に言うと、コンパイル時の型がCで実行時型がR(RはCまたはCから派生したクラス)のインスタンスで引数リストAを使用してNという名前のメソッドが呼び出されると、呼び出しは次のようになります。次のように処理されます...: http: //msdn.microsoft.com/en-us/library/aa645767 (v = vs.71).aspx

しかし、上で太字になっていることに気づきました。次のようなコードがあるとしましょう。

class Planet{
  public string Name;
  public float Size;
  public virtual void SpinPlanet(){
     Console.WriteLine("Hoooraaay!!!");
  }
}

class Earth : Planet{

}

そして、私のコードのどこかで私はします:

Earth world = new Earth();
world.SpinPlanet();

この場合:

  • NSpinPlanet()
  • CEarth
  • RPlanet

では、どうしてRコンパイル時型の派生クラスを得ることができるのでしょうかC。基本クラスタイプは実行時に解決されていませんか?

4

2 に答える 2

3

あなたは間違っています-コンパイル時のタイプ(C)はEarth であり、実行時のタイプ(R) Earthです。あなたが指摘する仕様の部分は、ここでは実際には関係ありません。

関連するのはhttp://msdn.microsoft.com/en-us/library/aa691356(v=vs.71).aspxで、具体的には次のとおりです。

メソッド呼び出しの候補メソッドのセットが作成されます。以前のメンバールックアップ(セクション7.3)で見つかったMに関連付けられたメソッドのセットから始めて、セットは引数リストAに関して適用可能なメソッドに縮小されます。

の唯一の候補実装は、派生クラスではなく、SpinPlanetの基本クラスにあります。Earth

参照する仕様の一部は、コードが次の場合に適用されます。

Planet world = new Earth();
world.SpinPlanet();

(特にEarthがのオーバーライドを定義した場合SpinPlanet)コンパイルタイプ(変数のタイプ)は。Planetになりますが、ランタイムタイプはになりますEarth

于 2012-04-18T17:55:04.770 に答える
2

呼び出す正しいメソッドは、仮想メソッドテーブルから選択することにより、実行時に解決されます。だからあなたがに追加する場合Earth

class Earth : Planet{
   public override void SpinPlanet(){
     Console.WriteLine("Hoooraaay Earth!!!");
  }
}

このようなコードで

Planet world = new Earth();
world.SpinPlanet(); //even if declared type Planet, 
                    // the real type remain Earth, so its  method will be called

メソッドが呼び出されますEarth's

私の例では、コンパイル時のタイプはですPlanetが、実行時のタイプはEarthです。

あなたの例では、コンパイル時と実行時のタイプは同じEarthです。

于 2012-04-18T17:52:38.327 に答える