Analyze the details of packing and unpacking in C

  • 2020-05-10 18:45:23
  • OfStack

Boxing and unboxing are operations 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
The above two sentences are not difficult to understand, but in the depth of understanding, it takes some space to explain.
Let's first look at what happens when you box, here's a line of the simplest box code, okay

object obj = 1;

This line assigns the integer constant 1 to a variable of type object, obj; It is well known that the constant 1 is the value type, which is to be placed on the stack, while object is the reference type, which is to be placed on the heap; Placing the value type on the heap requires one boxing operation.
The IL code for this line is as follows, please note the comments section:

.locals init (
  [0] object objValue
)  // The above 3 line IL Said the statement object The name of the type is objValue Local variable of 
IL_0000: nop
IL_0001: ldc.i4.s 9 // Represents the number of the integer 9 On the top 
IL_0003: box [mscorlib]System.Int32 // perform IL box Instruction, apply in the memory heap System.Int32 The heap space required by the type 
IL_0008: stloc.0 // Pops a variable on the stack and stores it to the index as 0 In a local variable 

The above is the operation to be performed by the 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 look at the unpacking operation again:
See the C# code below:

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 the reference type object variable objValue; Then perform another unpacking operation to store the reference variable objValue stored on the heap into the local plastic value type variable value.
Again, we need to look at the IL code:

.locals init (
  [0] object objValue,
  [1] int32 'value'
) // The above IL Declare two local variables object The type of objValue and int32 The type of value variable 
IL_0000: nop
IL_0001: ldc.i4.4 // Put the integer number 4 The pressure into the stack 
IL_0002: box [mscorlib]System.Int32  // perform IL box Instruction, apply in the memory heap System.Int32 The heap space required by the type 
IL_0007: stloc.0 // Pops a variable on the stack and stores it to the index as 0 In a local variable 
IL_0008: ldloc.0// The index for 0 Is a local variable (i.e objValue Variables) pushed onto the stack 
IL_0009: unbox.any [mscorlib]System.Int32 // perform IL  Unpacking instructions unbox.any  Will reference the type object Converted to System.Int32 type 
IL_000e: stloc.1 // Store the data on the stack to the index as 1 The local variable of value

The unboxing operation is performed in reverse of the boxing operation by converting the reference type values stored on the heap to value types and giving value type variables.
Boxed and unboxed operations require additional cpu and memory resources, so generics were introduced after c# 2.0 to reduce boxed and unboxed operations.

Related articles: