为什么必须最后指定new()约束?

时间:2011-02-24 19:55:15

标签: c# .net generics constraints

C#编译器需要最后指定new()约束。 根据MSDN:

  

与其他人一起使用时   约束,new()约束必须   最后指定。

为什么会有这样的限制?

3 个答案:

答案 0 :(得分:13)

因为规范是这样说的。它可能是这样说的,因为它使得解析约束更容易一些。允许您以任何顺序指定约束几乎没有价值,我可以想象一些成本(包括机会成本!)使其成为可能。

注意,实际上,规范并不只是说你必须最后有构造函数约束,如果有的话。它实际上说你必须按照以下顺序拥有约束

  1. 主要约束。
  2. 次要约束。
  3. 构造函数约束。
  4. 如果主要约束是指定类型参数的约束必须是引用类型或值类型,则辅助约束是指定基类或接口的约束,而构造函数约束是此处讨论的约束。

    规范的相关部分是§10.1.5,绝对值得一读。

答案 1 :(得分:0)

因为在其他约束(例如类)上,您可以指定构造函数,而在其他约束上则不能(接口)。

因此,如果new()首先出现,然后是接口上的约束,则会出现错误,因为您不能在接口上使用new()约束。

答案 2 :(得分:0)

YAQAPD:关于解析方向的另一个问题

每种编程语言都有自己的规则。解析的方向就是其中之一。 让我更详细地解释一下(耐心等待)。

假设您在Pascal / Delphi中编写以下函数:

function Sum2Numbers (n1, n2:integer) : integer;
begin
   result:=n1+n2;
end;

现在,C中的功能相同:

int function Sum2Numbers (int n1, int n2)
{
  return (n1+n2);
}

对于程序员来说,两个函数都做同样的事情(事实上他们确实这样做了)。 然而,在幕后,每个编译器都以自己的方式工作。

Pascal / Delphi和许多其他语言通过解析LEFT TO RIGHT中的文本来编译代码。 所以,当我们称之为帕斯卡或德尔福的函数,编译器把堆栈中,第一n1和{第二{1}}。 在C同样的功能做它从右到左,即编译器放于堆,第一n2和{第二{1}}。

两个编译器都在他们知道的ORDER中读取堆栈中的参数,所以一切正常。

所有 “C-家庭” 语言(C,C ++,托管C ++,C ++ / CLI,C#,...)他们使用的从右到左解析代码的顺序。

这就是为什么必须在约束列表的FAR RIGHT中指定n2约束的原因。 在使用它们之前,编译器必须知道需要创建类实例的IN ADVANCE。