Skip to content
Search lessons, topics, tests…
Esc

    ↑ ↓ moveEnter openEsc close

    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.

    Text
    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 box instruction 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.
    Sign in to mark lessons done and keep your place in the course.Sign in