What is the difference between boxing/unboxing and type casting?
Often, the terms seem to be used interchangeably.
What is the difference between boxing/unboxing and type casting?
Often, the terms seem to be used interchangeably.
Boxing and unboxing is a subset of type casts. Boxing is the act of treating a value type as reference type (which in practice, involves copying the contents of that value type (from stack) to the heap and returning a reference to that object). This allows a value type to be passed wherever a compatible reference type is expected. It also allows virtual method calls and other features of reference types to be performed on the value type. Unboxing is the reverse of this operation (getting back a value type out of a boxed object).
Type cast is the term used for any type of conversion from a variable of specific type to another. It's a broader concept.
A few minutes ago I answered a related question that covers this difference. To summarize, I categorized different types of IL instructions generated by C# cast operator:
box
IL instruction) and unboxing (unbox
IL instruction)dynamic_cast<Type>
in C++, uses castclass
IL instruction to verify)static_cast<Type>
in C++, there are plenty of IL instructions for different types of casts between primitive types)op_XXX
method).Boxing is the term for turning a value type (int, double, float, Guid, etc.) into a reference type (System.Object, System.String, etc.). Doing this boxing operation allocates memory on the heap (which the garbage collector will eventually need to reclaim). Unboxing is the reverse of this process, taking a reference type and turning it into a value type.
Casting is taking a type (say, System.Object) and treating it as another type (say, System.String).
When you box something in C#, you are casting it to another type. The difference is that it allocates additional memory as a new reference type is created.
Bottom line: boxing is a special kind of cast that converts a value type to a reference type, which requires the allocation of a new reference type.
Boxing/unboxing and type casting are two different operations, however they use the same syntax.
They are only used interchangeably when the person talking about it doesn't know what's really happening...
Boxing is storing a value type as an object on the heap, and unboxing is reading the value from the object. You can only unbox the value as it's exact type.
Casting is when you convert a basic type to another basic type (like from an int
to a long
), or when you change the type of a reference (like from List<int>
to IEnumerable<int>
).
Boxing refers to a conversion of a non-nullable-value type into a reference type or the conversion of a value type to some interface that it implements (say int
to IComparable<int>
). Further, the conversion of an underlying value type to a nullable type is also a boxing conversion. (Caveat: Most discussions of this subject will ignore the latter two types of conversions.)
For example,
int i = 5;
object o = i;
converts i
to an instance of type object
.
Unboxing refers to an explicit conversion from an instance of object
or ValueType
to a non-nullable-value type, the conversion of an interface type to a non-nullable-value type (e.g., IComparable<int>
to int
). Further, the conversion of a nullable type to the underlying type is also an unboxing conversion. (Caveat: Most discussion of this subject will ignore the latter two types of conversions.)
For example,
object o = (int)5;
int i = (int)o;
converts the integer boxed in o
to an instance of type int
.
A type cast is an explicit conversion of an expression to a given type. Thus
(type) expression
explicitly converts expression
to an object of type type
.
Boxing means converting a value type variable (i.e. an integer) to a reference type. Unboxing is the reverse of that, using type casting. In the .NET world, everything derives from the "object" type in a nutshell.
For example (C# example):
int myInt = 0; // original variable (unboxed to begin with)
object boxed = myInt; // box it up
int myIntUnBoxed = (int)boxed; // and unbox it again using type casting
The take-away from this is the unification of the type system, allowing value-types to be treated as reference types. This article has a more indepth look at boxing/unboxing.