Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is some ordering enforced in generic parameter constraints?

Tags:

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()
like image 622
George Duckett Avatar asked Dec 15 '11 15:12

George Duckett


People also ask

What is the idea behind constraints when talking about generics )?

Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type. They declare capabilities that the type argument must have, and must be placed after any declared base class or implemented interfaces.

What is generic parameters in C#?

Generics were added in C# 2.0. Generics are classes, structures, interfaces, and methods that have placeholders (type parameters) for one or more of the types that they store or use. A generic collection class might use a type parameter as a placeholder for the type of objects that it stores.

Can a generic class have multiple constraints?

There can be more than one constraint associated with a type parameter. When this is the case, use a comma-separated list of constraints. In this list, the first constraint must be class or struct or the base class.


1 Answers

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.

like image 189
Eric Lippert Avatar answered Oct 11 '22 02:10

Eric Lippert