What is the difference between boxing/unboxing and type casting?
Asked Answered
L

6

91

What is the difference between boxing/unboxing and type casting?

Often, the terms seem to be used interchangeably.

Lapidate answered 6/7, 2009 at 2:17 Comment(1)
I had to read both of the top 2 answers here to get a good idea of what the difference is, but I think I've got a pretty firm grasp nowChang
S
58

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.

Schnapp answered 6/7, 2009 at 2:29 Comment(4)
Thank you. There seems to be no standard language concerning these things.Lapidate
There is very standard language concerning these things. See the C# Language Specification, ECMA #334.Schnapp
For clarity, when Jason says "the conversion of an underlying value type to a nullable type is also a boxing conversion" what he means by "nullable type" is a Reference type, which can be set to null--hence his use of the term "nullable". What he does NOT mean is the Nullable<T> type. Casting a Value Type to a Nullable<T> (aka T?) is NOT an example of boxing/unboxing because no reference type is created. For example int? x = 5 is an example of a type cast, NOT boxing.Thoracoplasty
"For example int? x = 5 is an example of a type cast, NOT boxing." For completeness, it's an example of an IMPLICIT type cast, unlike the explicit type cast example Jason gave.Saundra
M
32

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:

  1. Boxing (box IL instruction) and unboxing (unbox IL instruction)
  2. Casting through the inhertiance hierarchy (like dynamic_cast<Type> in C++, uses castclass IL instruction to verify)
  3. Casting between primitive types (like static_cast<Type> in C++, there are plenty of IL instructions for different types of casts between primitive types)
  4. Calling user defined conversion operators (at the IL level they are just method calls to the appropriate op_XXX method).
Microscopium answered 6/7, 2009 at 2:19 Comment(5)
That doesn't help me very much. I guess I'll do some research on the internet to find specific definitions to compare.Lapidate
I wouldn't say boxing/unboxing are a subset of casting at all. They are about moving value types to reference types, so they can be altered/stored else where. Where-as casting is the process of re-interrupting a reference type.Shoran
@Simeon: from a language design perspective, a boxed int is just a different type and you are converting between different types.Microscopium
Where-as a would think of it as the same type (they both are int's, for example) but different ways of storing an int. But then from a C back ground it's just pointers to me.Shoran
@Simeon: It's the wrong way to think about boxing. Probably a direct artifact of thinking of stack/heap distinction for it. As I said, semantically, it's just converting a value type to a type with reference characteristics. Note that unlike int*, it's still immutable. And it's not really just 4 bytes on the heap. It has type information and call virtual methods on it: object o = 5; string s = o.ToString(); works because of that. This is impossible to do with a simple int*. In C++, this involves vtables, ... and boxing has to handle this stuff too.Microscopium
W
22

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.

Wendalyn answered 6/7, 2009 at 2:23 Comment(11)
Thank you! This is the kind of answer I am looking for!Lapidate
Heap is an implementation detail.Schnapp
That 'heap' detail actually helps me understand it better!Lapidate
Not quite true. First of all, it's not necessarily System.Object but actually any reference type. For example IComparable<int> i = 5 results in boxing too. Second, boxing is not the only cast that requires memory allocation. User defined casts are free to do so too. Third, as Jason pointed out, heap is the implementation detail. The important thing is treating a value type by reference type semantics not where it's allocated.Microscopium
That's understandable, just be careful that you don't let your understanding of the implementation details affect your understanding of the semantics. The important thing here is not how it comes to be that, say, a value type becomes a reference type, but what it means.Schnapp
There are times when I think programmers are overly pedantic. This is one of those times.Wendalyn
Yes. If boxing didn't allocate a new object on managed heap, it would no longer be boxing, and Microsoft would have to rewrite their own documentation: msdn.microsoft.com/en-us/library/yz2be5wk.aspxWendalyn
To clarify, the above comment was written in response to Jason's comment, which apparently has since been deleted.Wendalyn
I'd say in the generic sense 'heap meaning not stack memory' has to be taken for granted. not just an implementation detail. that is unless value types being stack based is also an implementation detail, at which point all that value type less than size X should also be forgotten.Shoran
@Judah: My question was the following: if boxing was not implemented using a heap, would it still be called "boxing"? Microsoft states the following in the page that you link to: "Boxing is the process of converting a value type to the type object or to any interface type implemented by this value type. When the CLR boxes a value type, it wraps the value inside a System.Object and stores it on the managed heap." Note that they tell you what boxing is without reference to the heap. Then they tell you how the CLR implements boxing. Also, check p. 114 of the ECMA 334 spec: no mention of heap.Schnapp
Do we honestly need to get into a debate about the heap being an implementation detail when the poster simply asked for the difference between casting and boxing? My answer was correct -- the CLR allocates memory on the heap to do boxing. You correctly point out, albeit pedantically, that the heap is an implementation detail. I can retort, "But it's the current implementation, a noteworthy one, and unlikely to change in the foreseeable future." --- HONESTLY --- We're devolving into silliness with this kind of pedantic banter.Wendalyn
C
6

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>).

Calix answered 6/7, 2009 at 2:23 Comment(1)
I know that. I'm asking what the differences are!Lapidate
O
4

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.

Opinionative answered 6/7, 2009 at 2:36 Comment(2)
Hasn't the Basic language always allowed value/reference types to be treated the same? Is this a C# specific thing?Lapidate
You could say that the idea of boxing/unboxing came from the Basic language (pre-VB.NET that is). It's not limited to C#, as the same concepts can be applied to VB.NET or any other language that targets the .NET runtime. It's been a long while since I've coded in the Basic language... ah the memories.Opinionative
C
0

Boxing (Implicit)

  • Process of converting Value type to Reference type
  • Or to any interface type implemented by the value-type.
  • when CLR boxes a value type, it wraps the value inside a System.Object.Instance and store it on the managed heap
  • Example
    int number = 12;
    object box = number;

Unboxing (Explicit)

  • Process of converting Reference type to Value type
  • Or from any interface-type to any value-type that implements the interface-type
  • Type casting require in this scenario.
  • Example
    object box = 12;
    int number = (int)box;
Cuckoopint answered 8/1, 2022 at 3:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.