在 C# 中,任何用户定义的 struct
自动成为 System.Struct System.ValueType
和 System.Struct 的子类 System.ValueType
是 System.Object
的子类。
但是当我们将一些结构分配给对象类型引用时,它会被装箱。例如:
struct A
{
public int i;
}
A a;
object obj = a; // boxing takes place here
所以我的问题是:如果 A
是 System.Object
的后代,编译器不能将它向上转换为对象类型而不是装箱吗?
最佳答案
结构是一种值类型。 System.Object
是引用类型。运行时以不同方式存储和处理值类型和引用类型。对于要被视为引用类型的值类型,有必要对其进行装箱。从底层的角度来看,这包括将值从它原来所在的堆栈复制到堆上新分配的内存中,其中还包含一个对象头。引用类型需要额外的头文件来解析它们的 vtables 以启用虚拟方法分派(dispatch)和其他引用类型相关的功能(请记住,堆栈上的结构只是一个值并且它具有零类型信息;它不包含任何类似 vtables 的东西并且可以' 直接用于解析动态调度的方法)。此外,要将某物视为引用类型,您必须有一个指向它的引用(指针),而不是它的原始值。
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# 确实隐藏了你的拳击操作不错。您没有明确提及任何内容来装箱该值,因此您可以简单地认为编译器已经为您“升级”了该结构。它正在为值制造继承和多态性的错觉,而它们没有直接提供多态行为所需的任何工具。
关于c# - 为什么结构需要装箱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1978589/