Raymond Lewallen

Sponsors

The Lounge

Wicked Cool Jobs

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Boxing and Unboxing for Beginners

Value types are created on the stack.  Reference types are created on the heap.  When something is created on the heap (an object) the variable assigned to that object holds a 4 byte “pointer” to the address space on the heap where the object has been allocated.  Every time you pass that variable as a parameter to another method, the 4 byte pointer is passed, not the object itself.  When you pass a value type (Integer, DateTime and such), a copy is made and the entire value type is copied to the method where its going to be used.

In the near future, I have a post in the making on using value types versus reference types.

Sometimes, you need to use a value type as if it were a reference type.  This is known as “boxing”.  Let’s say you wanted to create an arraylist that contains Integers.

    Public Sub Method1()

        Dim a As New ArrayList

        a.Add(10)

    End Sub

If you examine the Add method of an arraylist, you see that it is not overloaded.  It only take System.Object as a parameter.  System.Object is a reference type is any objects are created on the heap.  In the first paragraph, we know that Int32 is a value type.  So what happens when we add an integer to an arraylist?  Let’s look at the MSIL

.method public instance void Method1() cil managed
{
      // Code Size: 23 byte(s)
      .maxstack 2
      .locals (
            [mscorlib]System.Collections.ArrayList list1)
      L_0000: nop
      L_0001: newobj instance void [mscorlib]System.Collections.ArrayList::.ctor()
      L_0006: stloc.0
      L_0007: ldloc.0
      L_0008: ldc.i4.s 10
      L_000a: box int32
      L_000f: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)
      L_0014: pop
      L_0015: nop
      L_0016: ret
}

At L_0008, you see that we load the 4 byte integer 10 to the stack, you see the IL instruction to box that value as the next instruction.  So what is actually being stored in the arraylist?  Well we know that since arraylist takes an object as its parameter, we know that it wants to store an address pointer, not the value ‘10’.  In order to get an address pointer to store in the arraylist, the integer has to be converted to an object and a reference to that object must be obtained.  This is called boxing.

So what is really happening during boxing?  Just like any object, memory on the heap must be allocated for the object.  The Int32’s information is then copied to that new address space.  The address pointer of that location where the Int32’s information was copied to is returned.  The Int32, a native value type, is now an object: a reference type.  That address pointer is what actually gets passed to the Add method of the arraylist.

So what about unboxing?  Unboxing is the exact opposite of boxing.

    Public Sub Method1()

        Dim a As New ArrayList

        a.Add(10)

        Dim b As Int32

        b = a(0)

    End Sub

In this code, we create an Int32 and want to store the value from the first element of the arraylist to this Integer, in this case ‘10’.  Unboxing is defined as getting the address of the object, and then copying that information to a value type that has been created on the stack (b in the above example).  The MSIL is below:

.method public instance void Method1() cil managed
{
      // Code Size: 36 byte(s)
      .maxstack 2
      .locals (
            [mscorlib]System.Collections.ArrayList list1,
            int32 num1)
      L_0000: nop
      L_0001: newobj instance void [mscorlib]System.Collections.ArrayList::.ctor()
      L_0006: stloc.0
      L_0007: ldloc.0
      L_0008: ldc.i4.s 10
      L_000a: box int32
      L_000f: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)
      L_0014: pop
      L_0015: ldloc.0
      L_0016: ldc.i4.0
      L_0017: callvirt instance object [mscorlib]System.Collections.ArrayList::get_Item(int32)
      L_001c: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.IntegerType::FromObject(object)
      L_0021: stloc.1
      L_0022: nop
      L_0023: ret
}

You can see at instruction L_001c, the FromObject method is called.  This does the work of unboxing that we mentioned above.  2 imporant exceptions to take note of when unboxing though.  If the reference that are “getting” from the arraylist is nothing, a NullReferenceException will occur.  If the reference type that you are “getting” isn’t an Int32 in the above example, let’s say its a System.DateTime, then a InvalidCastException will occur.

So you’ve probably heard to avoid boxing and unboxing when you can.  Why?  Obviously, its costly to the speed and memory of your application.  Extra instructions and memory space are required when boxing and unboxing.  Also when you box a value type (recall this required allocating memory space on the heap), you always risk having the garbage collector run against the heap to clean up unused resources, which is an expensive operation.


Posted Thu, Jul 28 2005 7:48 PM by Raymond Lewallen

[Advertisement]

Comments

Jason Haley wrote Interesting Finds
on Fri, Jul 29 2005 7:30 PM
OdeToCode Links wrote OdeToCode Links For July 31
on Sun, Jul 31 2005 6:53 PM

Secret SQL Reporting Services Perfmon counters uncovered!

Scott C. Reynolds has a great comeback...
Daniel Moth wrote Boxing
on Sun, Jul 31 2005 7:06 PM
I don't really have anything to add to that post other than a couple of comments on the Intermediate Language:
Albert Smiley wrote re: Boxing and Unboxing for Beginners
on Mon, May 21 2007 5:52 PM

I am really interested in boxing and I don't really know where to begin. Please advise and send to the email above. Thank you in advance

Albert

Hari wrote re: Boxing and Unboxing for Beginners
on Fri, Jul 27 2007 9:04 AM

Hi thanks for your comments in boxing and unboxing am a beginer to this concept can you mail me about this in detail am very much interested in it

Mahesh wrote re: Boxing and Unboxing for Beginners
on Thu, Nov 15 2007 2:16 PM

excellent real world example for beginners

The boxers world » Boxing and Unboxing for Beginners wrote The boxers world » Boxing and Unboxing for Beginners
on Thu, Dec 6 2007 12:45 PM

Pingback from  The boxers world »  Boxing  and Unboxing for Beginners

J Leonard wrote re: Boxing and Unboxing for Beginners
on Wed, Apr 30 2008 12:05 AM

This is NOT for beginners. To read this article you need to have a very deep understanding of Assembly language, stacks, heaps, and C#. Nowhere is it explain WHY you would want to box or unbox. What's the whole point? Who knows.

Aj wrote re: Boxing and Unboxing for Beginners
on Wed, Aug 27 2008 2:14 AM

Why only Boxed type are unboxed? Any idea.

p90x wrote p90x
on Tue, Oct 7 2008 1:12 PM

Okay slight exaggeration, BUT, entering in my 10 digit phone number and using my index fingerprint to get through the turnstile is pretty high tech for a quick sweat. And this is just a regular 24 Hour Fitness Center… not ultra, not even sport.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Devlicio.us