Boxing and unboxing are operations to be performed to convert between value types and reference types.
1. Boxing occurs when a value type is converted to a reference type.
2. Unboxing occurs when a reference type is converted to a value type.
It is not difficult to understand the above two sentences, but if you go deeper, It takes some space to explain.
Let’s first look at what happens during boxing. The following is the simplest line of boxing code
object obj = 1;
This line of statement assigns the integer constant 1 to the object type variable obj; as we all know, the constant 1 is Value types, value types need to be placed on the stack, and object is a reference type, which needs to be placed on the heap; to put the value type on the heap, a boxing operation needs to be performed.
The IL code of this line of statement is as follows. Please pay attention to the comment part:
.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的局部变量中
The above is the operation to be performed for boxing. When performing boxing operation, it is inevitable to apply for memory space on the heap. And copy the value type data on the stack to the applied heap memory space, which will definitely consume memory and CPU resources. Let’s take a look at how the unboxing operation works:
Please look at the following C# code:
object objValue = 4; int value = (int)objValue;
The above two lines of code will perform a boxing operation to box the integer constant 4 into a reference type object variable objValue; and then perform an unboxing operation to store the reference variable objValue stored on the heap into the local integer value type variable value.
We also need to look at the IL code:
.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
Boxing operations and unboxing operations consume additional CPU and memory resources, so generics were introduced after c# 2.0 to reduce the consumption of boxing operations and unboxing operations.
For more detailed explanations of boxing and unboxing in C#, please pay attention to the PHP Chinese website!