.net の内部では、特定のメンバーを含む構造体の定義は、同じフィールドとメンバーを持ち、.NET から継承するクラスの定義と同じSystem.ValueType
です。class
コンパイラは、を継承する a を宣言することを許可しませんが、 aをValueType
宣言するstruct
と、コンパイラは「舞台裏で」継承するクラスを宣言することに注意してください。
.net で値型を特別なものにしているのは、ランタイムがストレージの場所 (変数、フィールド、パラメーターなど) を割り当てる方法です。継承していない型のストレージの場所ValueType
が宣言されると、ランタイムはヒープ オブジェクトにスペースを割り当てます。参照。対照的に、継承元の型の格納場所ValueType
が宣言されている場合、ランタイムはその型のすべてのパブリック フィールドとプライベート フィールドに領域を割り当てます。のような型の場合int
、システムは、通常の型システムの外で、特別なプリミティブ型のプライベート フィールドを割り当てます。
値型の格納場所は、実際にはその型のインスタンスを保持していないことに注意してください。代わりに、その型のインスタンスであり、その型のすべてのフィールドを保持します。like ステートメントは、 value-type instanceをstruct1 = struct2
instance に置き換えません。代わりに、の対応するフィールドからすべてのフィールドをコピーします。同様に、値型の格納場所がキーワードを使用せずにメソッドとしてプロシージャに渡された場合、渡されるのは構造体インスタンス自体ではなく、そのフィールドの内容です。struct1
struct2
struct2
struct1
ref
値型の保存場所を派生していない型ValueType
(Object
または などIComparable
) の 1 つにコピーする必要がある場合、システムは値型の新しいヒープ オブジェクト インスタンスを作成し、すべてのフィールドを値型からその場所にコピーします。新しいインスタンスを作成し、その新しいインスタンスへの参照をターゲット ストレージの場所に格納します。このプロセスは「ボクシング」と呼ばれます。ほとんどのコンパイラはこれを暗黙的に行うため、値型の格納場所が から派生したオブジェクトを保持しているかのように動作しようとしますValueType
。ただし、これは幻想であることに注意することが重要です。型X
が から派生しY
、X
名前付きxx
とY
名前付き がありyy
、実行するxx = yy
場合、そのようなステートメントはxx
、yy
同じオブジェクト インスタンスを参照します。から派生したもののインスタンスを保持していても、xx
とyy
が から派生した型ではない場合に発生します。ただし、and/orが から派生している場合は発生しません。その場合、システムはフィールドをあるインスタンスから別の (場合によっては新しい) インスタンスにコピーします。ValueType
yy
ValueType
xx
yy
ValueType