当一个值类型被装箱时,它被放置在一个无类型的引用对象中。那么是什么导致了无效的强制转换异常呢?
long l = 1;
object obj = (object)l;
double d = (double)obj;
当一个值类型被装箱时,它被放置在一个无类型的引用对象中。那么是什么导致了无效的强制转换异常呢?
long l = 1;
object obj = (object)l;
double d = (double)obj;
不,它没有放在无类型的对象中。对于每种值类型,CLR 中都有一个装箱的引用类型。所以你会有类似的东西:
public class BoxedInt32 // Not the actual name
{
private readonly int value;
public BoxedInt32(int value)
{
this.value = value;
}
}
该盒装类型在 C# 中不能直接访问,尽管它在 C++/CLI 中。显然,它知道原始类型。所以在 C# 中,你必须有一个object
变量的编译时类型,但这并不意味着它是对象的实际类型。
有关更多详细信息,请参阅ECMA CLI 规范或通过 C# 的 CLR。
Jon Skeet 的回答涵盖了原因;至于如何绕过它,这是你必须做的:
long l = 1;
object obj = (object)l;
double d = (double)(long)obj;
双重演员的原因是这样的;当 .NET 对变量进行拆箱时,它只知道如何将其拆箱为它所装箱的类型(long
在您的示例中)。一旦您将其拆箱并且您拥有适当的long
原语,您就可以将其强制转换为double
或任何其他类型从long
.