CodeOath
← All posts
C#65 min total · 17 parts

C# Fundamentals: Value Types, Reference Types, Boxing, and the Type System

Contents — Part 8 of 17: Boxing and Unboxing
Part 8 of 17 · ~1 min

Boxing and Unboxing

Sometimes a value type needs to be treated as an object — passed to an API that only accepts object, or stored in a non-generic collection. That requires boxing: wrapping the value in a heap-allocated box.

int number = 42;
object boxed = number;      // boxing: allocates a heap object wrapping 42
int unboxed = (int)boxed;   // unboxing: copies the value back out

Boxing isn't free — it's a heap allocation plus a copy, and it happens more often than people expect, including implicitly:

// Implicit boxing — easy to miss because there's no visible cast
Console.WriteLine("Value: " + 42); // 42 (an int) is boxed to be treated as an object for string concatenation

// A classic hidden-boxing bug: adding int values to a non-generic ArrayList
ArrayList list = new ArrayList();
list.Add(1);   // boxes 1
list.Add(2);   // boxes 2
int sum = (int)list[0] + (int)list[1]; // unboxes both to add them

This is exactly why generics matter for performance, not just type safety: List<int> stores real int values directly in a contiguous array, with zero boxing — a non-generic ArrayList typed to hold object boxes every single value type inserted into it, and the allocation and GC pressure from that adds up fast in a hot loop.