【问题标题】:.NET: Value type inheritance - technical limitations?.NET:值类型继承——技术限制?
【发布时间】:2011-06-26 10:07:29
【问题描述】:

我想知道为什么 .NET 值类型不支持继承(忽略接口实现)是否有任何技术原因......我乍一看想不出为什么值类型不应该允许单基类继承。

(我的意思是,可以说,如果你最终得到一个巨大的继承层次结构,值类型的继承会很糟糕,但我主要想知道是否存在任何运行时限制而不是实际限制。)

谢谢。

【问题讨论】:

    标签: c# .net runtime internals value-type


    【解决方案1】:

    考虑为值类型分配的内存。 CLR 确切地知道为值类型的变量分配多少空间,因为它知道将有哪些字段。它不可能以具有更多字段的子类型值结束。

    现在我们可以拥有值类型继承,它只是截断了一些东西:

    ExtendedValueType evt = new ExtendedValueType(...);
    BaseValueType bvt = evt;
    // Now you couldn't cast back to ExtendedValueType, because we'd have lost
    // information
    

    同样,值本身也没有类型信息,因此任何被扩展类型覆盖的虚方法都不会通过bvt 调用,因为就所有方面而言,值就是 只是 BaseValueType 的值。换句话说,很多“自然”继承特性会丢失,我认为这会引起很多混乱。

    【讨论】:

    • 啊,这当然有道理。但是,在类型信息说明中,值类型上的 .GetType() 是如何工作的呢?由于保证 ValueType 和 Object 没有字段,这是否只是微不足道的工作?
    • @Zor:它将值装箱,然后调用GetType。装箱知道类型,因为相关的存储位置被静态类型化为确切的值类型。具有讽刺意味的是,这意味着您甚至可以在值类型上获得 NullReferenceException,如果它是具有空值的可空值类型:)
    【解决方案2】:

    我认为值类型不支持继承的原因在于它们在内存中的表示方式。值类型所表示的数据的大小以及因此而导致的数据取决于其组成字段。也就是说,如果您的值类型包含一个 int 和一个字符串,则 32 位系统上的总大小将为 8,或 4(int 大小)+ 4(指针大小)。这意味着值类型在内存中表示的是一个字节块,没有任何更多信息。

    现在对比一下类类型,它们都是指针的大小,或者在 32 位系统上为 4。由于类类型的实例是指针,因此它们可以引用继承所需的内容,例如 VMT(虚拟方法表)和对父类信息的引用。这是值类型无法做到的事情,也是值类型不支持继承的原因。

    【讨论】:

      【解决方案3】:

      假设它可以完成。

      您将能够重复使用某些实现。
      但是继承的真正好处是替换和多态。它们需要按引用使用。

      这就是为什么支持接口实现的原因,因为它总是涉及拳击。但这不适用于继承。

      【讨论】:

      • 值类型的接口实现并不总是涉及装箱。您可以将接口用作值类型的通用约束,然后无需装箱即可调用其方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多