ボックス化とアンボックス化は、値型と参照型の間で変換するために実行される操作です。
1. 値型が参照型に変換されるときにボックス化が発生します
2. 参照型が値型に変換されるときにアンボックス化が発生します
上記 2 つの文は理解するのが難しくありませんが、深く理解するには時間がかかります。説明する余地があります。
まずボクシング中に何が起こるかを見てみましょう
object obj = 1;
このステートメント行は、ご存知のとおり、整数定数 1 をオブジェクト型変数 obj に割り当てます。 、値の型がスタックに配置され、オブジェクトが参照型である場合は、ヒープに配置する必要があります。値の型をヒープに配置するには、ボックス化操作が必要です。
この行の IL コードは次のとおりです: コメント部分に注意してください:
.locals init ( [0] object objValue ) //以上三行IL表示声明object类型的名称为objValue的局部变量 IL_0000: nop IL_0001: ldc.i4.s 9 //表示将整型数9放到栈顶 IL_0003: box [mscorlib]System.Int32 //执行IL box指令,在内存堆中申请System.Int32类型需要的堆空间 IL_0008: stloc.0 //弹出堆栈上的变量,将它存储到索引为0的局部变量中
上記はボックス化操作を実行する際に、メモリ領域の適用が避けられません。型データはヒープにコピーされ、値がスタックに保存されます。これにより、メモリと CPU リソースが確実に消費されます。ボックス化解除操作がどのように機能するかを見てみましょう:
次の C# コードを見てください:
object objValue = 4; int value = (int)objValue;
上記の 2 行のコードは、整数値定数 4 を参照型オブジェクト変数 objValue にボックス化するボックス化操作を実行します。次に、アンボックス操作を実行し、ヒープ上に格納されている参照変数 objValue をローカルの整数値型変数 value に格納します。
IL コードも確認する必要があります:
.locals init ( [0] object objValue, [1] int32 'value' ) //上面IL声明两个局部变量object类型的objValue和int32类型的value变量 IL_0000: nop IL_0001: ldc.i4.4 //将整型数字4压入栈 IL_0002: box [mscorlib]System.Int32 //执行IL box指令,在内存堆中申请System.Int32类型需要的堆空间 IL_0007: stloc.0 //弹出堆栈上的变量,将它存储到索引为0的局部变量中 IL_0008: ldloc.0//将索引为0的局部变量(即objValue变量)压入栈 IL_0009: unbox.any [mscorlib]System.Int32 //执行IL 拆箱指令unbox.any 将引用类型object转换成System.Int32类型 IL_000e: stloc.1 //将栈上的数据存储到索引为1的局部变量即value
ボックス化操作とボックス化解除操作は追加の CPU リソースとメモリ リソースを消費するため、ボックス化操作とボックス化解除操作の消費を削減するために C# 2.0 以降にジェネリックが導入されました。
C# でのボックス化とアンボックス化の詳細な説明については、PHP 中国語 Web サイトに注目してください。