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

发布于 2024-08-28 18:01:39 字数 158 浏览 9 评论 0原文

当值类型被装箱时,它被放置在无类型引用对象内。 那么是什么原因导致这里出现无效的强制转换异常呢?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情泪▽动烟 2024-09-04 18:01:39

不,它没有放置在无类型对象中。对于每种值类型,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 了解更多详细信息。

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:

public class BoxedInt32 // Not the actual name
{
    private readonly int value;
    public BoxedInt32(int value)
    {
        this.value = value;
    }
}

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.

雄赳赳气昂昂 2024-09-04 18:01:39

乔恩·斯基特(Jon Skeet)的回答说明了原因;至于如何解决它,这是你必须做的:

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

双重演员的原因是这样的;当 .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:

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

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 proper long primitive, you can then cast it to double or any other type castable from long.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文