ECMA-334: 11.3.1 Boxing conversions
Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio
| C# Language Specification |
|
| © 2006 ECMA International |
11.3.1 Boxing conversions
A boxing conversion permits any non-nullable-value-type to be implicitly converted to object or
System.ValueType or to any interface-type implemented by the non-nullable-value-type. Furthermore,
there is an implicit boxing conversion from any enumeration type to System.Enum. Boxing a value of a
non-nullable-value-type consists of allocating an object instance and copying the value-type value into that
instance. A boxing conversion is also permitted on a nullable-type. A nullable type T? has boxing
conversions to the same set of types as T. A boxing conversion from a nullable type T? is processed as
follows:
- If the source value is
null(HasValueproperty isfalse), the result is a null reference of the target type.
- Otherwise, the result is a reference to a boxed
Tproduced by unwrapping and boxing the source value.
[Note: As a consequence of this, if v is a value of a nullable type and vb is the result of boxing v, then the
four expressions vb==null, v==null, null==vb, and null==v produce the same result.
The actual process of boxing a value of a value-type is best explained by imagining the existence of a boxing
class for that type. For example, for any value-type T, the boxing class behaves as if it were declared as
follows:
sealed class T_Box { T value; public T_Box(T t) { value = t; } }
Boxing of a value v of type T now consists of executing the expression new T_Box(v), and returning the
resulting instance as a value of type object. Thus, the statements
int i = 123; object box = i;
conceptually correspond to
int i = 123; object box = new int_Box(i);
Boxing classes like T_Box and int_Box above don’t actually exist and the dynamic type of a boxed value
isn’t actually a class type. Instead, a boxed value of type T has the dynamic type T, and a dynamic type
check using the is operator can simply reference type T. For example,
int i = 123; object box = i; if (box is int) { Console.Write("Box contains an int"); }
will output the string "Box contains an int" on the console.
A boxing conversion implies making a copy of the value being boxed. This is different from a conversion of
a reference-type to type object, in which the value continues to reference the same instance and simply is
regarded as the less derived type object. For example, given the declaration
struct Point { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; } }
the following statements
Point p = new Point(10, 10); object box = p; p.x = 20; Console.Write(((Point)box).x);
will output the value 10 on the console because the implicit boxing operation that occurs in the assignment
of p to box causes the value of p to be copied. Had Point been declared a class instead, the value 20
would be output because p and box would reference the same instance. end note]