views:

2444

answers:

5

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

Often, the terms seem to be used interchangeably.

+3  A: 

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).
Mehrdad Afshari
That doesn't help me very much. I guess I'll do some research on the internet to find specific definitions to compare.
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.
Simeon Pilgrim
@Simeon: from a language design perspective, a *boxed int* is just a different type and you are converting between different types.
Mehrdad Afshari
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.
Simeon Pilgrim
@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.
Mehrdad Afshari
+1  A: 

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.

Judah Himango
Thank you! This is the kind of answer I am looking for!
Heap is an implementation detail.
Jason
That 'heap' detail actually helps me understand it better!
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.
Mehrdad Afshari
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.
Jason
There are times when I think programmers are overly pedantic. This is one of those times.
Judah Himango
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: http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx
Judah Himango
To clarify, the above comment was written in response to Jason's comment, which apparently has since been deleted.
Judah Himango
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.
Simeon Pilgrim
@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.
Jason
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.
Judah Himango
+2  A: 

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

Guffa
I *know* that. I'm asking what the differences are!
Thank you! That's what I was looking for!
+6  A: 

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.

Jason
Thank you. There seems to be no standard language concerning these things.
There is very standard language concerning these things. See the C# Language Specification, ECMA #334.
Jason
+2  A: 

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.

arabian tiger
Hasn't the Basic language always allowed value/reference types to be treated the same? Is this a C# specific thing?
(i.e. Variants)
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.
arabian tiger