【发布时间】: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
我看到了下面这行代码:
class Sample<T,U> where T:class where U: struct, T
在上面的例子中,参数U是值类型,它派生自引用类型T。
那条线怎么可能合法?
此外,如果值类型继承自引用类型,内存分配在哪里:堆还是堆栈?
【问题讨论】:
标签: c# .net memory-management type-parameter
与另一个答案相反,除了 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.ValueType 或 System.Enum(派生自 System.ValueType),这是根据您是否声明 struct 来选择的或enum。这两者本身就是引用类型,这有点令人困惑......
【讨论】:
所有结构都隐式地派生自 ValueType 类型。您不能指定显式基类型。
请参阅codemelt 发布的this MSDN tutorial on structs。
【讨论】:
MSDN 说,
结构没有继承 有上课。结构不能 从另一个结构或类继承, 它不能是一个类的基础。 然而,结构体继承自 基类对象。一个结构可以 实现接口,它做到了 就像类一样。
【讨论】:
萨沙写道:
如果不允许继承, 那么为什么以下合法:
class Samplewhere T:class where U:结构,T
在上述情况下,参数 U 为 值类型,它派生自 T -- 引用类型
尽管从通用合同的角度来看这是合法的,但您永远不会得到任何使用该类进行编译的有用代码,因为除了 T=System.Object 之外,您永远不会有满足 U 约束的类型。您可能会认为这是 C# 中泛型实现中的一个非常小的错误。
【讨论】:
结构不能从 System.ValueType 或 System.Enum 以外的任何东西继承。结构无法从普通引用类型继承。所以不幸的是,这个问题无法回答。
【讨论】: