Thursday, December 16, 2010

Value Type, Reference type & Boxing & Unboxing


 While drawing my one notes I gone through many contrasting views about where reference & value type are stored so i delved further by searching through many experts comment ,I collected following information most of it is from MSDN as it is authentic source for such information.I Wish the dust be settle down so that programmer can get better idea of it.

a) Value Types: The value types consist of two main categories namely Structs & Enumerations. Structs fall into these categories Numeric types, bool & User defined structs. Numeric types can be again of three types Integral types, Floating-point types &decimal types
Main Features of Value Types: Variable that are based on value types directly contains a values. Assigning one value type variable to another copies the contained value. This differs from the assignment of reference type variables, which copies a reference to the object but not the object itself. All value types are derived implicitly from the System.ValueType.
    Unlike reference types, it is not possible to derive a new type from a value type. However, like reference types, structs can implement interfaces.
   Unlike reference types, it is not possible for a value type to contain the null value. However, the nullable types feature does allow values types to be assigned to null.
   Each value type has an implicit default constructor that initializes the default value of that type.
Value types are implicitly derived from system.ValueType, which in turn derived from System.Object. Deriving from system.ValueType is not allowed. Even individual   value types like int are sealed.
Primitive types: The primitive types are identified through keywords.
      E.g. int k;
     Keywords are aliases for predefined types in the System namespace. In our Example above ‘int’ is an alias for system.int32. So instance of int i.e. ‘k’ can be treated as instances of system.int32.
      Constant expressions, whose operands are all primitive types constants, are evaluated at                compilation time.
      Primitive types can be initialized using literals. For example, 'A' is a literal of the type    char and 2001 is a literal of the type int.
Initializing Value Types
Local variables in C# must be initialized before being used. Therefore, if you declare a local variable without initialization like this:
int myInt;
you cannot use it before you initialize it. You can initialize it using the following statement:
myInt = new int();  // Invoke default constructor for int type.

which is equivalent to:
myInt = 0;
You can, of course, have the declaration and the initialization in the same statement like this:
int myInt = new int();
–or–
int myInt = 0;

Using the new operator calls the default constructor of the specific type and assigns the default value to the variable. In the preceding example, the default constructor assigned the value 0 to myInt.

With user-defined types, use new to invoke the default constructor.
 For example, the following statement invokes the default constructor of the Point struct:
Point p = new Point (); // Invoke default constructor for the struct.
After this call, the struct is considered to be definitely assigned; that is, all of its members are initialized to their default values.

All Value types are derived from System.ValueType, which in turn derived from system.Object.Point to note that one can’ t derived from System.ValueType. Value types do not take null value.
A variable that is of type value directly contains a value. Assigning a variable of type value to another variable of type value COPIES that value.

b) Reference Type:

Reference types inherit directly from System.Object. Reference types are stored on the managed heap, thus they are under the control of Garbage Collector.
Two or more reference type variables can refer to a single object in the heap, allowing operations on one variable to affect the object referenced by the other variable. The variable representing the instance contains a pointer to the instance of the class
c) Value Type vs. Reference Type:
  • A variable that is of type value directly contains a value. Assigning a variable of type value to another variable of type value COPIES that value.
  • A variable of type reference, points to a place in memory where the actual object is contained. Assigning a variable of type reference to another variable of type reference copies that reference (it tells the new object where the place in memory is), but does not make a copy of the object.
  • Value types are stored on the stack.
  • Reference types are stored on the heap.
  • Value types can not contain the value null. *
  • Reference types can contain the value null.
  • Value types have a default implied constructor that initializes the default value.
  • Reference types default to a null reference in memory.

  • Value types derive from System.ValueType.
  • Reference types derive from System.Object.

  • Value types cannot derive a new type from an existing value type, but they are able to implement interfaces.
  • Reference types can derive a new type from an existing reference type as well as being able to implement interfaces.
  • Changing the value of one value type does not affect the value of another value type.
  • Changing the value of one reference type MAY change the value of another reference type.
  • The nullable type (only in .NET 2.0) can be assigned the value null.
c) Boxing: Boxing is a process of converting a value type into a reference type. Boxing is used to store value types in the garbage-collected heap. It is an implicit conversion of a Value Types to the type object or to any interface type implemented by this value type.
Boxing a value type allocates an object instance on the heap and copies the value into the new object.
Boxing Conversion
 
It also possible to perform the boxing explicitly but seldom needed.
int i = 123;
object o = (object)i;  // explicit boxing

Example
This example converts an integer variable i to an object o by means of boxing. Then, the value stored in the variable i is changed from 123 to 456. The example shows that the original value type and the boxed object use separate memory locations, and therefore can store different values.
class TestBoxing
{
    static void Main()
    {
        int i = 123;
        object o = i;  // implicit boxing
 
        i = 456;  // change the contents of i
 
        System.Console.WriteLine("The value-type value = {0}", i);
        System.Console.WriteLine("The object-type value = {0}", o);
    }
}
 

Output

The value-type value = 456
The object-type value = 123
d) Unboxing: Unboxing is process of converting a reference type to value type. It extracts the value type from the object.
Unboxing is an explicit conversion from the type object to a value type or from an interface type to a value type that implements the interface.
 An unboxing operation consists of:
·         Checking the object instance to make sure it is a boxed value of the given value type.
·         Copying the value from the instance into the value-type variable.
The following statements demonstrate both boxing and unboxing operations:
int i = 123;      // a value type
object o = i;     // boxing
int j = (int)o;  // unboxing

The following figure demonstrates the result of the preceding statements.
Unboxing Conversion
 
For the unboxing of value types to succeed at run time, the item being unboxed must be a reference to an object that was previously created by boxing an instance of that value type. Attempting to unbox null or a reference to an incompatible value type will result in an InvalidCastException.
Example
The following example demonstrates a case of invalid unboxing and the resulting InvalidCastException. Using try and catch, an error message is displayed when the error occurs.
class TestUnboxing
{
    static void Main()
    {
        int i = 123;
        object o = i;  // implicit boxing
 
        try
        {
            int j = (short)o;  // attempt to unbox
 
            System.Console.WriteLine("Unboxing OK.");
        }
        catch (System.InvalidCastException e)
        {
            System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message);
        }
    }
}
 

Output

Specified cast is not valid. Error: Incorrect unboxing.
If you change the statement:
int j = (short) o;
to:
int j = (int) o;
the conversion will be performed, and you will get the output:
Unboxing OK.

Performance

In relation to simple assignments, boxing and unboxing are computationally expensive processes. When a value type is boxed, an entirely new object must be allocated and constructed. To a lesser degree, the cast required for unboxing is also expensive computationally.

No comments:

Post a Comment