CLR如何知道盒装对象的类型?

时间:2010-04-16 09:05:32

标签: c# clr type-conversion boxing

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

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

3 个答案:

答案 0 :(得分:17)

不,它不是放在一个无类型的对象中。对于每种值类型,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 specCLR via C#

答案 1 :(得分:9)

答案 2 :(得分:6)

Jon Skeet的答案涵盖了原因;至于如何绕过它,这就是你要做的事情:

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

双重演员的原因是这样的;当.NET取消对变量进行解包时,它只知道如何将其拆分为它所装箱的类型(在您的示例中为long。)一旦取消装箱并且您有一个正确的long原语,然后,您可以将其转换为double或来自long的任何其他类型的可投射。