【发布时间】:2010-04-16 09:05:32
【问题描述】:
当一个值类型被装箱时,它被放置在一个untyped引用对象中。 那么是什么导致了这里的无效转换异常呢?
long l = 1;
object obj = (object)l;
double d = (double)obj;
【问题讨论】:
标签: c# clr type-conversion boxing
当一个值类型被装箱时,它被放置在一个untyped引用对象中。 那么是什么导致了这里的无效转换异常呢?
long l = 1;
object obj = (object)l;
double d = (double)obj;
【问题讨论】:
标签: c# clr type-conversion boxing
不,它没有放在无类型的对象中。对于每种值类型,CLR 中都有一个装箱的引用类型。所以你会有 something 比如:
public class BoxedInt32 // Not the actual name
{
private readonly int value;
public BoxedInt32(int value)
{
this.value = value;
}
}
尽管它在 C++/CLI 中,但在 C# 中不能直接访问该盒装类型。显然,它知道原始类型。因此,在 C# 中,变量的编译时类型必须为 object,但这并不意味着这是对象的实际类型。
请参阅ECMA CLI spec 或CLR via C# 了解更多详情。
【讨论】:
long l = 40L; object o = (object)l; Console.WriteLine(o.GetType()); 在这种情况下,System.Int64 被打印到屏幕上。即使o 是一个对象,其底层类型仍然是一个long。
Jon Skeet 的回答涵盖了原因;至于如何绕过它,这是你必须做的:
long l = 1;
object obj = (object)l;
double d = (double)(long)obj;
双重演员的原因是这样的;当 .NET 对变量进行拆箱时,它只知道如何将其拆箱为从其拆箱的类型(在您的示例中为 long。)一旦您将其拆箱并且您拥有适当的 long 原语,您就可以进行强制转换将其转换为 double 或来自 long 的任何其他类型。
【讨论】: