C# > Core C# > Variables and Data Types > Boxing and Unboxing
Boxing and Unboxing Example
This example demonstrates the concepts of boxing and unboxing in C#. Boxing is the process of converting a value type (e.g., `int`, `bool`, `struct`) to an object type. Unboxing is the reverse process, converting an object type back to its original value type. Understanding boxing and unboxing is crucial for optimizing performance in C# because they involve memory allocation and type checking.
Boxing a Value Type
In this code, an integer variable `i` (a value type) is assigned the value 123. Then, it's assigned to an object variable `o`. This process is called boxing. A new object is created on the heap, and the value of `i` is copied into this object. The object `o` now contains a boxed representation of the integer 123.
int i = 123;
object o = i; // Boxing: i is converted to an object
Unboxing a Value Type
Here, the object `o`, which contains the boxed integer, is converted back to an integer variable `j`. This is called unboxing. It involves retrieving the value stored inside the object `o` and assigning it to the integer variable `j`. Note the explicit cast `(int)o`. This is essential; without it, the compiler will throw an error because it can't implicitly convert an object to an integer.
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing: o is converted back to an int
Concepts Behind Boxing and Unboxing
Boxing and unboxing are fundamental to how C# bridges the gap between value types and reference types. All types in C# ultimately derive from `System.Object`. Boxing allows value types to be treated as objects, enabling them to be stored in collections (like `ArrayList`, although generics are preferred now), passed as parameters to methods that expect objects, and used in scenarios where object references are required. Unboxing retrieves the original value from the boxed object.
Real-Life Use Case
A common use case involves non-generic collections like `ArrayList`. Since `ArrayList` stores objects, value types are automatically boxed when added to the list. When retrieving values from the `ArrayList`, they must be unboxed to their original type. Note that using generic collections (`List
using System;
using System.Collections;
public class Example
{
public static void Main(string[] args)
{
ArrayList list = new ArrayList();
list.Add(10); // Boxing
list.Add("Hello"); // No Boxing
list.Add(3.14); // Boxing
int num = (int)list[0]; // Unboxing
double pi = (double)list[2]; // Unboxing
Console.WriteLine("Number: " + num);
Console.WriteLine("Pi: " + pi);
}
}
Best Practices
Interview Tip
Be prepared to explain the difference between value types and reference types, the mechanism of boxing and unboxing, and the performance implications of these operations. Understand when boxing and unboxing occur implicitly (e.g., when adding value types to a non-generic collection). Be ready to discuss how generics eliminate the need for much of boxing/unboxing.
When to use them
Ideally, minimize the use of boxing and unboxing by leveraging generics. Scenarios where boxing and unboxing might be unavoidable include:
Memory Footprint
Boxing increases memory consumption. When a value type is boxed, a new object is created on the heap. This object contains the value of the original value type along with additional overhead (type information, synchronization block index). Unboxing does not allocate new memory but reads directly from the heap the information allocated during boxing operation.
Alternatives
The primary alternative to boxing and unboxing is the use of generics. Generics provide type-safe collections and algorithms that operate directly on the specified type, avoiding the need to treat value types as objects. Using reflection carefully can avoid the need for boxing sometimes, but it comes with its own performance overhead.
Pros
Cons
FAQ
-
What happens if I try to unbox an object to the wrong type?
An `InvalidCastException` will be thrown at runtime. For example, trying to unbox a boxed integer to a `string` will result in this exception. -
Why is boxing and unboxing considered a performance issue?
Boxing involves allocating memory on the heap and copying the value type's data. Unboxing involves type checking and retrieving the data from the heap. These operations consume more resources than working directly with value types, especially when performed frequently.