Search content within the blog

Friday, April 17, 2009

Boxing and unboxing types

In C# data types are classified into two categories—value types and reference types. The difference between value type and reference type is that the variables of value type are allocated on stack, whereas, variables of reference type are allocated on heap. Secondly, the variable of value type contains data, whereas, variable of reference type contains the address of the memory location where data of that variable is stored. Among built-in data types, all the types of integers, floats, doubles, decimals, chars and bools are value types, whereas, the string and object are reference types. Among user-defined data types, classes, interfaces and delegates are reference types, whereas, structure is a value type.

Memory allocated for objects of value types is freed when they go out of scope. Memory allocated for objects of reference types is freed when they are no more being referenced.

Both the value and reference types have advantages and disadvantages. Memory allocation on stack is faster than that on heap. So, if the object is small, we must use a value type rather than a reference type. On the other hand, if the object is big we must avoid declaring it as a value type. Because, if we assign it to any other object, its whole contents would get copied, consuming additional memory. As against this, in case of a reference type only the reference is copied rather than the whole object.

Boxing Is Implicit

Boxing is an implicit conversion of a value type to the type Object. Boxing a value allocates an instance ofObjectand copies the value into the new object instance, as shown in Figure



Boxing is implicit when you provide a value type where a reference is expected. The runtime notices that you’ve provided a value type and silently boxes it within an object. You can, of course, first cast the value type to a reference type, as in the following:

int myIntegerValue = 5;
object myObject = myIntegerValue; // cast to an object
myObject.ToString();

This is not necessary, however, as the compiler boxes the value for you silently and with no action on your part:

int myIntegerValue = 5;
myIntegerValue.ToString(); // myIntegerValue is boxed

Unboxing Must Be Explicit

To return the boxed object back to a value type, you must explicitly unbox it. For the unboxing to succeed, the object being unboxed must really be of the type you indicate when you unbox it.

You should accomplish unboxing in two steps:

1. Make sure the object instance is a boxed value of the given value type.
2. Copy the value from the instance to the value-type variable.

Example 11-5 illustrates boxing and unboxing.

Example 11-5. Boxing and unboxing

using System;
public class UnboxingTest
{
public static void Main()
{
int myIntegerVariable = 123;

//Boxing
object myObjectVariable = myIntegerVariable;
Console.WriteLine( "myObjectVariable: {0}",
myObjectVariable.ToString() );

// unboxing (must be explicit)
int anotherIntegerVariable = (int)myObjectVariable;
Console.WriteLine( "anotherIntegerVariable: {0}",
anotherIntegerVariable );
}
}

Output:
myObjectVariable: 123 anotherIntegerVariable: 123

The next figure illustrates unboxing

Example 11-5 creates an integermyIntegerVariableand implicitly boxes it when it is assigned to the objectmyObjectVariable; then, to exercise the newly boxed object, its value is displayed by callingToString().

The object is then explicitly unboxed and assigned to a new integer variable,anotherIntegerVariable, whose value is displayed to show that the value has been preserved.



Boxing and unboxing are the processes that enable value types (such as, integers) to be treated as reference types (objects). The value is “boxed” inside an Object and subsequently “unboxed” back to a value type. It is this process that allowed you to call theToString()method on the integer in Example

No comments:

Post a Comment