クラスの値型の値は、マネージヒープ内のオブジェクトインスタンスと共存する必要があります。メソッドのスレッドのスタックは、メソッドの存続期間中のみ存続します。そのスタック内にのみ存在する場合、値はどのように持続できますか?
管理対象ヒープ内のクラスのオブジェクトサイズは、その値型フィールド、参照型ポインター、およびSyncブロックインデックスなどの追加のCLRオーバーヘッド変数の合計です。オブジェクトの値型フィールドに値を割り当てると、CLRはその値をその特定のフィールドのオブジェクト内に割り当てられたスペースにコピーします。
たとえば、単一のフィールドを持つ単純なクラスを考えてみましょう。
public class EmbeddedValues
{
public int NumberField;
}
そしてそれで、簡単なテストクラス。
public class EmbeddedTest
{
public void TestEmbeddedValues()
{
EmbeddedValues valueContainer = new EmbeddedValues();
valueContainer.NumberField = 20;
int publicField = valueContainer.NumberField;
}
}
.NET FrameworkSDKが提供するMSIL逆アセンブラーを使用して、EmbeddedTest.TestEmbeddedValues()のILコードを確認する場合
.method public hidebysig instance void TestEmbeddedValues() cil managed
{
// Code size 23 (0x17)
.maxstack 2
.locals init ([0] class soapextensions.EmbeddedValues valueContainer,
[1] int32 publicField)
IL_0000: nop
IL_0001: newobj instance void soapextensions.EmbeddedValues::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.s 20
IL_000a: stfld int32 soapextensions.EmbeddedValues::NumberField
IL_000f: ldloc.0
IL_0010: ldfld int32 soapextensions.EmbeddedValues::NumberField
IL_0015: stloc.1
IL_0016: ret
} // end of method EmbeddedTest::TestEmbeddedValues
CLRは、スタック内のロードされた値「20」を、ロードされたEmbeddValuesのNumberFieldフィールドの場所に直接管理対象ヒープにstfldするように指示されていることに注意してください。同様に、値を取得するときは、ldfld命令を使用して、その管理対象ヒープの場所からスレッドスタックに値を直接コピーします。これらのタイプの操作では、ボックス化/ボックス化解除は行われません。