Thursday 13 October 2011

Boxing and unboxing

WHAT:
Converting a value type to reference type is called Boxing. Unboxing is the opposite operation and is an explicit operation.

.NET provides a unified type system. All types including value types derive from the type object. It is possible to call object methods on any value, even values of primitive types such as int.

HOW:

class Test
{
static void Main() {
int i = 1;
object o = i; // boxing
int j = (int) o; // unboxing
}
}
WHY?
Boxing/unboxing occurs when a value type (like a struct, int, long) is passed somewhere that accepts a reference type - such as object.

This occurs when you explicitly create a method that takes parameters of type object that will be passed value types. It also comes up when you use the older non-generic collections to store value types (typically primitives).

You will also see boxing occuring when you use String.Format() and pass primitives to it. This is because String.Format() accepts a params object[] - which results in boxing of the additional parameters in the call.

Using reflection to invoke methods can also result in boxing/unboxing, because the reflection APIs have no choice but to return object since the real type is not known at compile time (and the Reflection APIs cannot be generic).

The newer generic collections do not result in boxing/unboxing, and so are preferable to the older collections for this reason (eg ArrayList, Hashtable, etc). Not to mention they are typesafe.

You can avoid boxing concerns by changing methods that accept objects to be generic. For example:

public void string Decorate( object a ) // passing a value type results in boxing
{
return a.ToString() + " Some other value";
}
vs:

public void string Decorate( T a )
{
return a.ToString() + " some other value";
}