@Rawling の回答に追加するには、次のような例を使用して実用的な例を示すことができます。
class Base
{
// base property
public virtual string Name
{
get { return "Base"; }
}
}
class Overriden : Base
{
// overriden property
public override string Name
{
get { return "Overriden"; }
}
}
class New : Base
{
// new property, hides the base property
public new string Name
{
get { return "New"; }
}
}
1.オーバーライド
オーバーライドされたプロパティの場合、基本クラスの仮想メソッドのスロットは別の実装に置き換えられます。コンパイラはメソッドをvirtualと見なし、実行時にオブジェクトの仮想テーブルを使用してその実装を解決する必要があります。
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new Overriden();
// Base.Name is virtual, so the vtable determines its implementation
Console.WriteLine(b.Name); // prints "Overriden"
Overriden o = new Overriden();
// Overriden.Name is virtual, so the vtable determines its implementation
Console.WriteLine(o.Name); // prints "Overriden"
}
2.隠れる
キーワードを使用してメソッドまたはプロパティを非表示new
にすると、コンパイラは派生クラスに対してのみ新しい非仮想メソッドを作成します。基本クラスのメソッドは変更されません。
変数の型がBase
(つまり、仮想メソッドのみを含む) 場合、その実装は vtable を通じて解決されます。変数の型が の場合New
、非仮想メソッドまたはプロパティが呼び出されます。
{
Base b = new Base();
Console.WriteLine(b.Name); // prints "Base"
b = new New();
// type of `b` variable is `Base`, and `Base.Name` is virtual,
// so compiler resolves its implementation through the virtual table
Console.WriteLine(b.Name); // prints "Base"
New n = new New();
// type of `n` variable is `New`, and `New.Name` is not virtual,
// so compiler sees `n.Name` as a completely different property
Console.WriteLine(n.Name); // prints "New"
}
3. まとめ
コードの一部が基本型を受け入れる場合、実行時に常に仮想テーブルが使用されます。ほとんどの OOP シナリオでは、これは、メソッドを としてマークするnew
ことは、まったく異なる名前を付けることに非常に似ていることを意味します。
4.インスタンス化後のオブジェクトサイズ
これらの型をインスタンス化しても、仮想テーブルのコピーは作成されないことに注意してください。各 .NET オブジェクトには、数バイトのヘッダーと、そのタイプのテーブルの仮想テーブルへのポインター ( class
) があります。
プロパティ (仮想ではないもの)に関してnew
は、基本的に thiscall セマンティクスを使用して静的メソッドとしてコンパイルされます。つまり、メモリ内のインスタンスのサイズにも何も追加されません。