In C#, each type of data is defined as a part of the programming language and all the variables used in our program must be defined with one of these data types. So, C# is a strongly typed programming language. The data types in C# is mainly of three types,
C# allows converting a Value Type to a Reference Type and vice-versa. This is done through boxing and unboxing respectively. Boxing and Unboxing provide a single view of the type system, allowing every type attribute to be viewed as an object.
It is the process of converting a Value Data Type to a Reference Data Type. This process is an implicit conversion and an object type is used. It consists of allocating an object instance and copying the Value Type value into that instance.
- using System;
- class Sample {
- static void Main() {
- int x = 100;
- object obj = x;
- System.Console.WriteLine("Before changing the value of x :");
- System.Console.WriteLine("The value of x is : {0}", x);
- System.Console.WriteLine("The value of obj is : {0}", obj);
- if(obj is int)
- {
- System.Console.WriteLine("The obj is of int type.");
- }
- x = 200;
- System.Console.WriteLine("After changing the value of x :");
- System.Console.WriteLine("The value of x is : {0}", x);
- System.Console.WriteLine("The value of obj is : {0}", obj);
- if(obj is int)
- {
- System.Console.WriteLine("The obj is of int type.");
- }
- }
- }
Output
Before changing the value of x,
The value of x is: 100
The value of obj is: 100
The obj is of int type.
After changing the value of x,
The value of x is: 200
The value of obj is: 100
The obj is of int type.
Explanation
Here, x is an integer variable and is assigned a value of 100 at the beginning. Now an object type variable obj is declared and instantiated with x. This leads to boxing wherein the value of x, that is, 100 is copied and a new object instance is created with the value of 100. We print the values of both ‘x’ and ‘obj’. Since the type of obj is int, the statement in the if block gets executed. Next, the value of x is changed to 200. But this does not affect the value stored in obj since it had been instantiated during runtime.
The object reference obj is created on the stack, which references a value of type int on the heap. The difference between the variable x and the object reference obj is illustrated in the following diagram,
An Important Note
Value Data Type variables are always stored in Stack memory whereas references in Reference Data Type variables are always stored in Heap memory.
What is Unboxing in C#?
Definition
It is the process of converting a Reference Data Type to a Value Data Type. This process is an implicit conversion. It consists of first checking whether the object instance is a boxed value of the given Value Type.
Syntax
- object objectName;
- dataType varName = (dataType) objectName;
Here, objectName is the name of the object instance that is to be unboxed. varName is the name of the variable into which the object instance will be unboxed into. The data type of both the variable and the object instance must be the same, otherwise, an exception will be thrown.
Example
Let us consider the following code:
- using System;
- class Sample {
- static void Main() {
- int x = 100;
- object obj = x;
- int y = (int)obj;
- System.Console.WriteLine("Before changing the value of obj :");
- System.Console.WriteLine("The value of x is : {0}", x);
- System.Console.WriteLine("The value of obj is : {0}", obj);
- System.Console.WriteLine("The value of y is : {0}", y);
-
-
- x = 200;
- obj = x;
- System.Console.WriteLine("After changing the value of obj :");
- System.Console.WriteLine("The value of x is : {0}", x);
- System.Console.WriteLine("The value of obj is : {0}", obj);
- System.Console.WriteLine("The value of y is : {0}", y);
-
- }
- }
Output
Before changing the value of obj,
The value of x is: 100
The value of obj is: 100
The value of y is: 100
After changing the value of obj,
The value of x is: 200
The value of obj is: 200
The value of y is: 100
Explanation
Here, x is an integer variable and is assigned the value 100 initially. Then x is boxed into obj using boxing. Now, obj is unboxed into another integer variable y using explicit unboxing. The variable y now contains the value 100. Now the value of x is changed and x is again boxed to obj. However, this does not affect the variable y since it has already been instantiated during its declaration.
The variables x and y are created on the stack. The object reference obj is created on the stack, which references a value of type int on the heap. The following diagram illustrates it,
The item being unboxed must be a reference to an object that was previously generated by boxing an instance of that value type for unboxing to succeed at run time. A NullReferenceException is thrown while attempting to unbox null. An InvalidCastException is thrown when attempting to unbox a reference to an incompatible value type.
Example to demonstrate incorrect unboxing,
Let us consider the following code,
- using System;
- class Sample {
- static void Main() {
- try
- {
- int x = 100;
- object obj = x;
- short y = (short)obj;
- System.Console.WriteLine("The value of x is : {0}", x);
- System.Console.WriteLine("The value of obj is : {0}", obj);
- System.Console.WriteLine("The value of y is : {0}", y);
- }
- catch (System.InvalidCastException e)
- {
- System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message);
- }
-
- }
- }
Output
The specified cast is not valid. Error: Incorrect unboxing.
Explanation
Here, the object reference obj is of type int but the variable y is of type short. So, when we try to unbox obj into the variable y we get an exception thrown which is caught by the catch block and the appropriate message is shown.
Conclusion
In C#,
boxing and unboxing help in the integration of the Value Data Types and the Reference DataTypes. This integration of the type systems gives value types the advantages of object-ness without adding excessive overhead. Int values are simply 32-bit values for programs that don't need int values to behave as objects. This functionality is available on-demand for programs that need int values to behave like objects.