Boxing and Unboxing in C#

Photo by EJ Li on Unsplash

Boxing and Unboxing in C#

In .NET, as with many other languages, we use Value types and Reference types. Value types are stored on the stack (if they are not contained inside a reference type), and Reference types are stored on the heap.

Boxing is taking a Value type and storing it in an Object (which is a reference type).

Here is an example:

short age = 25;
Object ageRef = age;

As can be seen, we have saved age into a reference type and now it resides on the heap.

Boxing can occur when we call an Object method on a Value type too, such as:

25.ToString();

In this case, the compiler creates an Object reference for us automatically.

In short, Boxing occurs any time you assign a Value type to an Object, and this includes passing Value types to a method that takes in an Object as the parameter type. For example:

void BoxIt(Object o) {
  // do something
}

BoxIt(5); // Boxing the value type

Because boxing creates a new Object reference, you cannot compare references of the same Value type values. For example:

Object.ReferenceEquals(5,5); // This will return false

We get false because 5 is a Value type and boxing causes the two parameters to have different references.

Unboxing is the opposite - think of it as opening up the Object and releasing the value out of it and storing it back to a Value type. This operation requires a cast.

short age = 25;
Object ageRef = age;
short oldAge = (short) ageRef;  // casting to a short

We know that the int value type is larger than the short type. Can we do the following?

short age = 25;
Object ageRef = age;
int bigAge = (int) ageRef;  // allowed?

The code above will throw a System.InvalidCastException exception. You cannot unbox and expect the casting rules to work.