CLR 如何知道装箱对象的类型?
当值类型被装箱时,它被放置在无类型引用对象内。 那么是什么原因导致这里出现无效的强制转换异常呢?
long l = 1;
object obj = (object)l;
double d = (double)obj;
When a value type is boxed, it is placed inside an untyped reference object.
So what causes the invalid cast exception here?
long l = 1;
object obj = (object)l;
double d = (double)obj;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,它没有放置在无类型对象中。对于每种值类型,CLR 中都有一个装箱引用类型。因此,您可能会遇到如下情况:
该装箱类型无法在 C# 中直接访问,但可以在 C++/CLI 中访问。显然它知道原始类型。因此,在 C# 中,变量必须具有编译时类型的
object
,但这并不意味着这是对象的实际类型。请参阅 ECMA CLI 规范 或 通过 C# 进行 CLR 了解更多详细信息。
No, it's not placed in an untyped object. For each value type, there's a boxed reference type in the CLR. So you'd have something like:
That boxed type isn't directly accessible in C#, although it is in C++/CLI. Obviously that knows the original type. So in C# you have to have a compile-time type of
object
for the variable but that doesn't mean that's the actual type of the object.See the ECMA CLI spec or CLR via C# for more details.
乔恩·斯基特(Jon Skeet)的回答说明了原因;至于如何解决它,这是你必须做的:
双重演员的原因是这样的;当 .NET 对变量进行拆箱时,它只知道如何将其拆箱为装箱时的类型(在您的示例中为
long
)。一旦您将其拆箱,您就拥有了正确的long
原语,然后您可以将其转换为double
或任何其他可从long
转换的类型。Jon Skeet's answer covers the why; as for the how to get around it, here's what you have to do:
The reason for the dual cast is this; when .NET unboxes the variable, it only knows how to unbox it into the type it was boxed from (
long
in your example.) Once you've unboxed it and you have a properlong
primitive, you can then cast it todouble
or any other type castable fromlong
.