Monday, July 9, 2007

What is Boxing and Unboxing?

Value type objects have two representations: an unboxed form and a boxed form. Reference types are always in a boxed form.

Boxing

Let's say that you wanted to create an ArrayList object to hold a set of Points. With each iteration of the loop, a Point value type is initialized and is stored in the ArrayList. The Add method is prototyped in the following manner:

public virtual void Add(Object value)

The previous code plainly shows that Add takes an Object which is a reference type as a parameter. But here we are passing a Point value type. For this code to work, the Point value type must be converted into a true heap-managed object, and a reference to this object must be obtained. Converting a value type to a reference type is called boxing.

Internally, here's what happens when a value type is boxed:

  • When the Add method is called, memory is allocated in the heap for a Point object. The amount of memory allocated is the size required by the value type plus any additional overhead to consider this value a true object. The additional overhead includes a pointer to a virtual method table and a pointer to a sync block.
  • The members currently residing in the Point value type (p) are copied into the newly allocated Point object.
  • The address of the Point object (a reference type) is returned and is then passed to the Add method.
  • The Point object will remain in the heap until it is garbage-collected. The Point value type variable (p) can be reused or freed since the ArrayList never knows anything about it.

Unboxing

Unboxing retrieves a reference to the value type (data fields) contained within an object.

Internally, the following is what happens when a reference type is unboxed:

  • The CLR first ensures that the reference type variable is not null and that it refers to an object that is a boxed value of the desired value type. If either test fails, then an InvalidCastException exception is generated.
  • If the types do match, then a pointer to the value type contained inside the object is returned.
  • The value type that this pointer refers to does not include the usual overhead associated with a true object: a pointer to a virtual method table and a sync block.

No comments: