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.