In C# Int
type is derived from ValueType
. ValueType
is derived from Object
type. Thus Int
is an Object
.
If every value type variable is already an Object
, then what actually happens during boxing/unboxing?
Think of Object
simply as a base class from which ValueType inherits, not a type that represents the behavior of the value type. Boxing puts the value type into a reference type wrapper that then makes the value type behave like an object.
From MSDN:
Both reference and value types are derived from the ultimate base class Object. In cases where it is necessary for a value type to behave like an object, a wrapper that makes the value type look like a reference object is allocated on the heap, and the value type's value is copied into it.
There is a particular memory layout for
Object
instances. To save space and for compatibility with native code (COM, p/invoke, etc), instances of value types do not conform to that layout."boxing" embeds the value inside an actual "object" instance with the expected layout. This enables polymorphic use by all the various functions that work on
object
instances and expect that interface.It's really not correct to say that
Int32
is a subclass ofObject
. "boxedInt32
" is, but "unboxedInt32
" instances do not have any base class subobject at all. (Among other things,object
layout includes a pointer to the actual most-derived type of the instance. The type of value-type objects is determined by their relationship to something else, they do not contain the type metadata. Or a monitor. Or all the other goodies ofobject
. Boxed versions do.)