Introduction
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,
- Value Data Type
The Value Data Types in C# will preserve the variable value directly in memory and support both signed and unsigned literals. There are mainly five types of Value Data Types in C#. They are: Signed and Unsigned Integral Types, Floating-Point Types, Decimal Types, Character Types, and Boolean Types.
- Reference Data Type
These data types do not store the variable value directly in memory but contain a memory address of the variable value. String, Objects are the built-in reference data types.
- Pointer Data Type
These data types store a memory address of the variable value. We use the ampersand (&) and the asterisk (*) operators to retrieve the data. The (&) operator determines the address of a variable while the (*) operator determines the value of an address.
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.
What is Boxing in C#?
Definition
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.
Syntax
- dataType varName;
- Object objectName = varName;
Here, varName is the name of the variable which is to be boxed into. objectName is the name of the object instance into which the variable will be boxed.
Example
Let us consider the following code,
- using System;
- class Sample {
- static void Main() {
- int x = 100;
- object obj = x; // Boxing x into obj
- 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) // Checking if the type of obj is int
- {
- System.Console.WriteLine("The obj is of int type.");
- }
- x = 200; // Changing the value of x
- 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) // Checking if the type of 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; // Boxing
- int y = (int)obj; // Unboxing
- 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; //Boxing
- 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);
- }
- }
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; // Boxing
- short y = (short)obj; // Unboxing with mismatched types
- 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);
- }
- }
- }
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.

Join the conversation! Your thoughts help the community grow.