在定义泛型类型参数的约束时,我们必须将class()
放在前面,将new()
放在最后,例如。
为什么会这样,为什么我不能按任何顺序设置约束?
除class
/ struct
之外,new()
最后是否还有其他限制?
示例:
protected T Clone<T>() where T : class, ICopyable<T>, new()
答案 0 :(得分:25)
选择该订单没有特别的理由。所选择的顺序从更一般到更具体,我认为这是一个相当不错的属性。
至于“为什么需要订单?”这个问题,实施和测试团队可以更容易地通过语言强加清晰,明确的命令。我们可以允许约束以任何顺序出现,但这会给我们带来什么?
我在语言上工作的时间越长,我就越觉得每次给用户一个选择时,你都给他们一个做出错误选择的机会。 C#的基本设计原则是我们告诉你什么时候出错了并强迫你做对了 - 这不是JavaScript的基本设计原则。它的基本设计原则是“混淆并尝试做用户的意思”。通过对C#中正确的语法进行更多限制,我们可以更好地确保在程序中很好地表达了预期的语义。
例如,如果我今天正在设计一种类似C#的语言,那么就不会有像我这样模糊的语法:
class C : X , Y
或
... where T : X, Y
Y显然是一个界面。是X?我们无法从语法上说出X是打算成为接口还是类。可以说这种模糊性使得检测基类型与接口中的周期等问题变得非常复杂。对于所有相关的事情来说,如果它更加冗长,就像在VB中一样。
答案 1 :(得分:1)
与大多数语法相关的问题一样,基本答案是因为规范说明了这一点。我们从C#5.0规范(第10.1.5节)
获得通用类型约束的以下语法type-parameter-constraints:
primary-constraint secondary-constraints constructor-constraint primary-constraint , secondary-constraints primary-constraint , constructor-constraint secondary-constraints , constructor-constraint primary-constraint , secondary-constraints , constructor-constraint
初级约束:
class-type class struct
次要约束:
interface-type type-parameter secondary-constraints , interface-type secondary-constraints , type-parameter
构造函数约束:
new ( )
Eric Lippert在解释为什么设计这种方式方面做得非常出色,所以我不会对此进行阐述。