【问题标题】:Is a boxed value just a pointer to a copy of the value stored in the managed heap?装箱值是否只是指向托管堆中存储的值副本的指针?
【发布时间】:2013-05-24 04:27:26
【问题描述】:

在我看来,这就是我认为的装箱和拆箱。而已。有人可以确认这是正确的吗?

【问题讨论】:

  • @Foo 我认为这是一个公平的问题和漂亮的图表。
  • 嗯,是/否问题通常是个坏主意。在 SO 上,我们希望答案包含两个或三个以上的字母。
  • @Servy - 但问题内容也可能不正确,然后您可以提供有关为什么不正确的更多详细信息。
  • @DarrenDavies 如果您知道任何应该关闭的问题,请投票关闭或标记适当的关闭原因。如果您不确定是否应该关闭它们,请在元/聊天上提出问题,其他人可以帮助您解决问题(如果应该关闭,也可能自己投票)。其他一些应该关闭的问题被遗漏了,但这并不意味着我们不应该关闭这个问题,因为它符合关闭的标准。
  • 如果你想弄清楚这个问题的优点,meta 比这里更好。

标签: c# boxing


【解决方案1】:

没有。

虽然总体思路是正确的,但它并不完全正确。装箱的值是符合System.Object 内存布局的完整对象。这意味着一个 v-table 指针(它为 System.Object 虚拟方法(例如 EqualsGetHashCode)提供特定于类型的重载,并用作防止拆箱到不兼容类型的类型标记)和 (可选)同步监视器。

存储在装箱值句柄中的实际地址并不指向内容,而是指向附加的元数据。

【讨论】:

  • 好答案。另外满足 OP 对“是”/“否”的需求
【解决方案2】:

.net 中的每个值类型实际上都定义了两种不同的类型:存储位置类型和堆对象类型。从外部的角度来看,堆类型的行为很像一个类

class Holder<T> where T:struct
{
  public T This;
  public override String ToString() { return This.ToString(); }
  public override bool Equals(object other) { return This.Equals(other); }
  etc.
}

which wraps 暴露了所有值类型的公共方法。然而,堆类型将具有一些额外的魔力,因为它将实现底层值类型实现的任何接口[如上,通过包装对值类型方法的调用]。此外,与堆对象关联的Type 将与与存储位置关联的Type 相同。

请注意,值类型存储位置保存值类型的实例并按照值语义运行,但引用类型存储位置保存堆对象引用(否则为 null)并按照可变引用语义运行(请注意,所有值类型,当装箱时,表现为可变引用类型);该系统并没有非常方便地提供突变,但是装箱的值类型实例可以在没有基础值类型对此事有任何发言权的情况下进行突变。

【讨论】:

    猜你喜欢
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多