c# - 为什么结构需要装箱?

标签 c# struct boxing

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

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

struct A
{
    public int i;
}

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

所以我的问题是:如果 ASystem.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/

相关文章:

c++ - 如何在不知道名称的情况下访问结构体成员?

c# - 扩展 System.Object 时如何避免装箱/拆箱?

c# - 当它是引用类型的字段时,值类型是否装箱?

C# 异步,等待

c - 实现链表时指针的奇怪问题

c# - Entity Framework 核心 : How to configure model with two One to Many relations in one entity referencing the same table

dictionary - 如何在Golang中使用与 map 中的键相同的数据来区分两种自定义结构类型?

java - 编译器错误 : reference to call ambiguous

c# - 我正在创建一个数组,我想从构造函数中指定它的长度

c# - 找不到 ildasm.exe