When a value type is boxed, it is placed inside an untyped reference object. So what causes the invalid cast exception here?
long l = 1;
object obj = (object)l;
double d = (double)obj;
Boxing is the process of converting a value type to the type object or to any interface type implemented by this value type. When the common language runtime (CLR) boxes a value type, it wraps the value inside a System. Object instance and stores it on the managed heap. Unboxing extracts the value type from the object.
The process of converting a Reference Type variable into a Value Type variable is known as Unboxing. It is an explicit conversion process.
Boxing and unboxing is a essential concept in C#'s type system. With Boxing and unboxing one can link between value-types and reference-types by allowing any value of a value-type to be converted to and from type object.
No, it's not placed in an untyped object. For each value type, there's a boxed reference type in the CLR. So you'd have something like:
public class BoxedInt32 // Not the actual name
{
private readonly int value;
public BoxedInt32(int value)
{
this.value = value;
}
}
That boxed type isn't directly accessible in C#, although it is in C++/CLI. Obviously that knows the original type. So in C# you have to have a compile-time type of object
for the variable but that doesn't mean that's the actual type of the object.
See the ECMA CLI spec or CLR via C# for more details.
Jon Skeet's answer covers the why; as for the how to get around it, here's what you have to do:
long l = 1;
object obj = (object)l;
double d = (double)(long)obj;
The reason for the dual cast is this; when .NET unboxes the variable, it only knows how to unbox it into the type it was boxed from (long
in your example.) Once you've unboxed it and you have a proper long
primitive, you can then cast it to double
or any other type castable from long
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With