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