15

当一个值类型被装箱时,它被放置在一个无类型的引用对象中。那么是什么导致了无效的强制转换异常呢?

long l = 1;
object obj = (object)l;
double d = (double)obj;
4

2 回答 2

18

不,它没有放在无类型的对象中。对于每种值类型,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

于 2010-04-16T09:09:02.977 回答
6

Jon Skeet 的回答涵盖了原因;至于如何绕过它,这是你必须做的:

long l = 1;
object obj = (object)l;
double d = (double)(long)obj;

双重演员的原因是这样的;当 .NET 对变量进行拆箱时,它只知道如何将其拆箱为它所装箱的类型(long在您的示例中)。一旦您将其拆箱并且您拥有适当的long原语,您就可以将其强制转换为double或任何其他类型从long.

于 2010-04-16T09:18:14.110 回答