6

2 つのクラスがAありB、B が A から派生する場合:

class A {}
class B : A { }

Btoのインスタンスを非常にうまくアップキャストできますA

B b = new B();
A a = b;

これで、 ECMA-335 (Common Language Infrastructure (CLI) Partitions I to VI)の 132 ページに記載されているように、ランタイムが基になる型が B であると判断する方法を理解できます。

インスタンス化された型のオブジェクトは、実行時に正確な型 (ジェネリック引数の型と数を含む) を回復するのに十分な情報を運ぶ必要があります。[理論的根拠: これは、キャストとテストのインスタンス、およびリフレクション機能を正しく実装するために必要です。

では、ランタイムは、基になる型がB実際にはA. で使用可能なメソッドが表示されないことはわかっていますBが、基になる型がBである場合、格納場所の型をどのように格納しますAか?

それは理にかなっていますか?

4

2 に答える 2

7

オブジェクトは B であり、CLI はそれが B であることを認識します。A について認識しているのは主にコンパイラであり、コンパイラはフィールドまたはローカルを型 A (または、メソッド チェーンなどの場合によっては型メソッドの戻り値の型によって認識され、呼び出し元のILにハード スタンプされます)。つまり、基本的には、呼び出しコード自体が「これは A だと思います」というものです。割り当てなどは通常、事前にすべて検証可能であるため、間違えるリスクはありません。IL をハッキングして故意に間違ったものにしようとすると、ランタイムが警告し、メソッドの実行を拒否します。これらの理由から、B であることがわかっている値を A ローカル/フィールドに割り当てる場合、型チェックは必要ありません。これは直接の割り当てにすぎません。

于 2012-10-23T19:11:44.910 に答える
3

オブジェクトの実際の型は、常にオブジェクト自体と共にヒープに格納されます。そのオブジェクトを指す参照は、その型が実際の型 (たとえば、その型の基本クラスまたは実装されたインターフェイス) から割り当て可能である限り、異なる型にすることができます。

ヒープ上のすべてのオブジェクトには、少量のデータが保存されています。そのオブジェクトの型はその 1 つです。

于 2012-10-23T19:12:04.770 に答える