为什么结构需要装箱? [英] Why do structs need to be boxed?

查看:18
本文介绍了为什么结构需要装箱?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C# 中,任何用户定义的 struct 自动是 System.Struct System.ValueTypeSystem.Struct 的子类 System.ValueTypeSystem.Object 的子类.

In C#, any user-defined struct is automatically a subclass of System.Struct System.ValueType and System.Struct System.ValueType is a subclass of System.Object.

但是当我们将一些结构分配给对象类型引用时,它会被装箱.例如:

But when we assign some struct to object-type reference it gets boxed. For example:

struct A
{
    public int i;
}

A a;
object obj = a;  // boxing takes place here

所以我的问题是:如果 ASystem.Object 的后代,编译器不能将它向上转换为对象类型而不是装箱吗?

So my question is: if A is an descendant of System.Object, can't the compiler up-cast it to object type instead of boxing?

推荐答案

结构是一种值类型.System.Object 是一个引用类型.值类型和引用类型由运行时以不同方式存储和处理.要将值类型视为引用类型,必须对其进行装箱.从低级的角度来看,这包括将值从它最初所在的堆栈复制到堆上新分配的内存中,该内存还包含一个对象头.引用类型需要额外的头来解析它们的 vtables 以启用虚拟方法分派和其他与引用类型相关的功能(请记住,堆栈上的结构只是一个值,它的类型信息为零;它不包含任何类似 vtables 的内容,并且可以'不能直接用于解析动态调度的方法).此外,要将某物视为引用类型,您必须有一个引用(指针)指向它,而不是它的原始值.

A struct is a value type. System.Object is a reference type. Value types and reference types are stored and treated differently by the runtime. For a value type to be treated as a reference type, it's necessary for it to be boxed. From a low level perspective, this includes copying the value from the stack where it originally lives to the newly allocated memory on the heap, which also contains an object header. Additional headers are necessary for reference types to resolve their vtables to enable virtual method dispatches and other reference type related features (remember that a struct on stack is just a value and it has zero type information; it doesn't contain anything like vtables and can't be directly used to resolve dynamically dispatched methods). Besides, to treat something as a reference type, you have to have a reference (pointer) to it, not the raw value of it.

所以我的问题是 - 如果 A 是 System.Object 的后代,不能编译器将其向上转换为对象类型而不是装箱?

So my question is - if A is an descendant of System.Object, can't compiler upcast it to object type instead of boxing?

在较低级别,值不继承任何东西.实际上,正如我之前所说,它并不是真正的对象.A 派生自 System.ValueType 而后者又派生自 System.Object 的事实是在您的编程语言 (C#) 的抽象级别定义的,而 C# 确实隐藏了你的拳击操作还不错.您没有明确提及将值装箱的任何内容,因此您可以简单地认为编译器已为您升级"了结构.它使值的继承和多态性错觉,而多态行为所需的任何工具都不是直接由它们提供的.

At a lower level, a value does not inherit anything. Actually, as I said before, it's not really an object. The fact that A derives from System.ValueType which in turn derives from System.Object is something defined at the abstraction level of your programming language (C#) and C# is indeed hiding the boxing operation from you pretty well. You don't mention anything explicitly to box the value so you can simply think the compiler has "upcasted" the structure for you. It's making the illusion of inheritance and polymorphism for values while none of the tools required for polymorphic behavior is directly provided by them.

这篇关于为什么结构需要装箱?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆