Why is some ordering enforced in generic parameter constraints?

落爺英雄遲暮 提交于 2019-11-29 16:36:03

问题


When defining a generic type parameter's constraints, we have to put class() at the front and new() at the end, for example.

Why is this, why can't I put my constraints in any order?

Are there any other restrictions on ordering besides class/struct first, new() at the end?


Example:

protected T Clone<T>() where T : class, ICopyable<T>, new()

回答1:


There's no particular reason why that order was chosen. The chosen order goes from more general to more specific, which I suppose is a reasonably nice property.

As for the question "why require an order at all?", it's simply easier on the implementation and testing teams to have a clear, unambiguous order imposed by the language. We could allow the constraints to come in any order, but what does that buy us?

The longer I work on languages the more I'm of the opinion that every time you give the user a choice, you give them an opportunity to make a bad choice. A basic design principle of C# is that we tell you when things look wrong and force you to make them right -- which is not a basic design principle of, say, JavaScript. Its basic design principle is "muddle on through and try to do what the user meant". By placing more restrictions on what is correct syntax in C# we can better ensure that the intended semantics are expressed well in the program.

For example, if I were designing a C#-like language today there is no way that I would have ambiguous syntaxes like:

class C : X , Y

or

... where T : X, Y

Y is clearly intended to be an interface. Is X? We can't tell syntactically whether X was intended to be an interface or a class. Suffice to say this ambiguity greatly complicates things like detecting cycles in base types vs interfaces and so on. It'd be much easier on all concerned if it were more verbose, as it is in VB.




回答2:


Like most syntax related questions, the basic answer is because the spec says so. We get the following grammar for generic type constraints from the C# 5.0 spec (Section 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 

primary-constraint:

class-type 
class 
struct 

secondary-constraints:

interface-type
type-parameter 
secondary-constraints   ,   interface-type
secondary-constraints   ,   type-parameter

constructor-constraint:

new (   )

Eric Lippert has done an excellent job of explaining why it was designed this way, so I won't expound on that.



来源:https://stackoverflow.com/questions/8522332/why-is-some-ordering-enforced-in-generic-parameter-constraints

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!