值类型被装箱后,会被放置在一个不带类型的引用对象中。 那么是什么导致了这里的无效转换异常?
long l = 1;
object obj = (object)l;
double d = (double)obj;
值类型被装箱后,会被放置在一个不带类型的引用对象中。 那么是什么导致了这里的无效转换异常?
long l = 1;
object obj = (object)l;
double d = (double)obj;
不,它没有放置在一个未类型化的对象中。对于每种值类型,在CLR中都有一个装箱的引用类型。所以你将会得到类似这样的结果:
No, 它不是放在一个未类型化的对象中. 对于每个值类型,在 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规范或CLR via C#。
Jon Skeet的回答涵盖了为什么会出现这种情况;至于如何避免它,以下是你需要做的:
long l = 1;
object obj = (object)l;
double d = (double)(long)obj;
long
)。一旦您对其进行了拆箱并且拥有了一个适当的long
基元,您就可以将其转换为double
或任何其他可从long
转换的类型。
long l = 40L; object o = (object)l; Console.WriteLine(o.GetType());
在这种情况下,屏幕上打印出了System.Int64。即使o
是一个对象,底层类型仍然是long。 - Anthony Pegram