【问题标题】:How can a struct inherit from a class in type parameters constrains?结构如何从类型参数约束中的类继承?
【发布时间】:2009-02-24 02:41:09
【问题描述】:

我看到了下面这行代码:

class Sample<T,U> where T:class where U: struct, T

在上面的例子中,参数U值类型,它派生自引用类型T

那条线怎么可能合法?
此外,如果值类型继承自引用类型,内存分配在哪里:堆还是堆栈?

【问题讨论】:

    标签: c# .net memory-management type-parameter


    【解决方案1】:

    与另一个答案相反,除了 T=System.Object 之外还有其他类型可以编译:

    class Samplewhere T:class where U:struct, T
    

    “T : class”约束实际上并不意味着 T 必须是一个类。这意味着 T 必须是引用类型。这包括接口,结构可以实现接口。因此,例如,T=IConvertible, U=System.Int32 效果很好。

    我无法想象这是一个特别常见或有用的约束条件,但它并不像乍看起来那样完全违反直觉。

    至于更笼统的观点:正如 Obiwan Kenobi 所说,这完全取决于您的观点。 CLI 规范对此有相当复杂的解释,其中“派生自”和“继承自”并不意味着完全相同的东西,IIRC。但是不,您不能指定值类型的基本类型 - 它始终是 System.ValueTypeSystem.Enum(派生自 System.ValueType),这是根据您是否声明 struct 来选择的或enum。这两者本身就是引用类型,这有点令人困惑......

    【讨论】:

    • 很好,先生。很明显,当我回答时,我并没有完全想到这一点。
    • 我可以想象将类型参数约束为实现某些变异接口的值类型会很有用的情况。结构实现变异接口通常是邪恶的,因为系统无法区分变异成员和非变异成员,并且没有提供任何方法来阻止结构声明可以禁止像装箱这样的隐式转换(这意味着一个人不能' t 转换为接口,但可以将其用作约束)。另一方面,尽管它们的使用受到限制,...
    • ...变异接口可以提供难以实现的语义(如果一个克隆方法具有克隆方法并使用它每次复制一个对象引用,或者有一个方法,给定两个对象实例,将改变一个以保存与另一个相同的数据,但是当需要值类型语义时,使用值类型可能会更有效)。
    • 一个问题先生,我可以/我可以从 c# 中的结构派生一个类吗?我认为这在 C++ 中是可能的。我在 C# 中尝试过,但我遇到了一些问题,可能是我不知道该怎么做?
    • @Dhananjay:不,你不能。你不能从 C# 中的结构派生任何东西。
    【解决方案2】:

    所有结构都隐式地派生自 ValueType 类型。您不能指定显式基类型。
    请参阅codemelt 发布的this MSDN tutorial on structs

    • 当你实例化一个结构时,例如作为局部变量,它们被分配在堆栈上(更好的性能)
    • 类可能包含结构作为成员 - 在这种情况下,它们被分配在堆上。

    【讨论】:

    • 请记住,在堆栈上分配结构并不一定意味着更好的性能。只有在某些情况下,您才能使用结构获得更好的性能,并且它们仅在这些情况下存在。
    • 在堆栈上分配一个大对象将需要许多副本,因为结构在方法之间传递。如果你的结构特别重,你可能会得到更差的性能。
    • @Sasha:它肯定回答了第一个问题!
    【解决方案3】:

    MSDN 说,

    结构没有继承 有上课。结构不能 从另一个结构或类继承, 它不能是一个类的基础。 然而,结构体继承自 基类对象。一个结构可以 实现接口,它做到了 就像类一样。

    【讨论】:

    【解决方案4】:

    萨沙写道:

    如果不允许继承, 那么为什么以下合法:

    class Samplewhere T:class where U:结构,T

    在上述情况下,参数 U 为 值类型,它派生自 T -- 引用类型

    尽管从通用合同的角度来看这是合法的,但您永远不会得到任何使用该类进行编译的有用代码,因为除了 T=System.Object 之外,您永远不会有满足 U 约束的类型。您可能会认为这是 C# 中泛型实现中的一个非常小的错误。

    【讨论】:

    • 因为 Sample 是合法的。 Sample 是合法的,仅此而已。
    【解决方案5】:

    结构不能从 System.ValueType 或 System.Enum 以外的任何东西继承。结构无法从普通引用类型继承。所以不幸的是,这个问题无法回答。

    【讨论】:

    • 或 System.Enum
    • @jon,哦,是的,忘了那个。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多