C# – Box(ing) and Un-box(ing)
I have heard this concept from many people and their different versions so I always wanted to share some insight on it which can work as a one stop solution.
What is boxing and un-boxing?
The Conversion of a value type into reference type is boxing and the reverse process is un-boxing.
What is Value Type?
Value Types in C# are the primitive data types such as Boolean, char,numeric, enum and structures.
Note: The value types are stored in stack if they are declared inside a method and are stored in heap if they are declared outside method and inside a reference type.
What is Reference Type?
Reference types are class, delegates, objects ,string and interface. A reference type is always stored in heap.
Converting Value types into reference types:
Let’s take a simple example.
int num = 5; // num is value type object obj = num; //obj is reference type
Let us go through the underlying steps to understand what really happens during boxing.
Statement 1: int num = 5;
- The numeric constant value 5 is pushed onto stack.
- The value is then popped into the local variable num.
Statement 2: object obj = num ; (Box)
- As the value type will be represented as object, the memory is allocated on heap. The amount of memory allocated will be equal to the size of the value type plus the memory sufficient to hold object and its internal structures.
- The Value type (num’s) value (5) is then copied to the newly allocated heap memory.
- The address of the object is stored on the stack which points to newly allocated heap memory.
Converting reference types to value types:
From the above example it is clear that we don’t need to do any explicit conversion when converting value type to a reference type. However, to un-box casting is necessary. This is because, the object is being converted to a type and the run-time can validate the cast.
int num = 5; object obj = num; int anotherNumber = (int)obj; // Un-boxing
Now, let us understand what happens during un-boxing.
Statement 3: Un-boxing
- First, The runtime validates the object, pointed by the address on the stack. If the value cannot be converted to the type specified in the instruction then, InvalidCastException is thrown. If the object is valid, then CLR proceeds further.
- The value of the instance (in this case 5) into the value type (int) variable (anotherNumber).
.NET features automatic type handling.
Why do I need to be careful about boxing and un-boxing?
It is true that nothing special needs to be done to take advantage of boxing. However, there is some overhead associated with the process of boxing and un-boxing which affects the performance of the code.
Let’s take a look at the code below:
int num = 5; object obj = num; Response.Write(num + ", " + (int)obj);
How many boxing and un-boxing operations can you spot?
The correct answer is not 2 box and 1 un-box operations as it appears. Infact, 3 boxing operations and 1 un-boxing operations are being carried out in total.
- The first statement is merely an assignment of a numeric value to value type.
- As shown in the example above, the second statement is ‘Boxing’.
- Now, the last statement is an interesting one. The MSIL instruction which is executed to obtain the result of Write method is “String.Concat”. Now, the closest overload method is String.Concat(object,object,object)
Num (value type) is converted into object – Boxing
“,” is already a reference type. Hence no conversion is necessary.
(int)obj – The conversion has to be performed here as this is an explicit conversion –Un-boxing
Un-boxed value of (int)obj is converted back to object to be passed as a parameter to the function – Boxing
So, the explicit cast of ‘obj’ in the function costs us a needless box and un-box.
What is the difference between boxing/un-boxing and up-casting/down-casting?
Boxing/Un-boxing are transformations between value and reference types. Casting just transforms the reference types of the objects.
Boxing takes copy of value from stack to heap and un-boxing takes value type from heap to stack. While, casting does not move the objects. It merely changes the reference types of the objects.
Please share your comments and feedback here or send it to firstname.lastname@example.org