Module 1 · How Boxing and Unboxing Work · Lesson 1 of 21
First principles: why boxing exists
1.1 One logical value, two physical contracts
An int can be treated as an object because C# presents a unified type system: every type can participate in operations exposed by object, and value types can implement interfaces.[S1] That language convenience hides a representation mismatch.
A normal value-type storage location contains the value’s fields inline. An object reference, by contrast, must identify a GC-managed object with object identity, runtime type metadata, synchronization/header state, and a payload that the GC can relocate as one unit.
INLINE VALUE CONTRACT MANAGED OBJECT CONTRACT
The storage location itself A reference points to an object body
contains the value bytes. recognized by the GC and runtime.
+----------------------+ allocation start
| x: int32 = 42 | +----------------------+
+----------------------+ | object header |
No object identity. +----------------------+ <- object ref points after header
No per-value MT pointer. | MethodTable* |
No independently movable object. +----------------------+
| payload bytes |
+----------------------+
Has identity and a runtime type.Definition
Boxing is the conversion of a value type to object, System.ValueType, System.Enum where applicable, or an interface implemented by the value type. Semantically, the runtime creates an object-shaped copy of the value and returns a managed reference to that object.[S1]
Unboxing validates that an object contains the requested value type and then exposes or copies its payload back into value-type form.
1.2 Why not merely point at the original value?
The original value may live in a stack frame that disappears, inside another movable object, in an array element, in a register, or in a temporary. A general object reference must remain valid independently of that storage location. It must also carry enough runtime type information for virtual methods, interface dispatch, type tests, and GC relocation.
Boxing solves these requirements by giving the value a separate managed object identity. The cost is a copy plus an allocation.
Under The Hood
- CLR / CTS: The Common Type System distinguishes value-type values from object references while defining boxing conversions between them.
- IL: The conversion is represented explicitly by the
boxinstruction in ordinary CIL. - JIT / CPU: The JIT lowers the operation into allocation fast-path work, header/MethodTable initialization, a payload copy, and publication of the resulting reference. Exact code depends on architecture and optimization tier.
- Memory / GC: The box is a managed object, normally born in generation 0. If a root keeps it alive, it can be promoted to generations 1 and 2.
- Performance: Complexity is still O(1) for one box, but the constant includes allocation, copying, later GC accounting, an extra indirection, and worse data density.