-
Notifications
You must be signed in to change notification settings - Fork 214
Allow constructors to restrict type arguments to class. #1899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
How would this play with #647, allowing constructors to have type arguments of their own? |
It would be unrelated to #647. Those constructor-specific extra type arguments go after the name, not after the class, and are not constrained by the class generics. You would be able to write |
In this particular case (where the constructor is named) it would be possible to use a static method rather than a constructor, yielding very similar results: class TreeSet<E> {
TreeSet.from(List<E> elements, int Function(E, E) compare);
static TreeSet<E> fromComparable<E extends Comparable<E>>(List<E> elements) =>
TreeSet.from(elements, Comparable.compare);
}
void main() {
TreeSet.fromComparable(['Hello!']); // OK, this works.
} The main differences would be
So the two approaches are not directly comparable, but there are are a whole range of reasons why this feature would enable certain things that we cannot do today. |
I have on rare occasions wanted this. It's not unreasonable. But I suspect the value is marginal enough that it would be hard to justify the cost of the feature. As Erik notes, you can usually just use a static method, or maybe a subclass. |
Currently the constructors a
class C<T> { ... }
must all accept all the same type arguments asC
.That sometimes leads code authors to restrict the type arguments programatically, like:
Here the goal is to have a constructor which only works with a non-nullable type.
Similar problems occur for other subtypes than nullability like:
where you can omit the
compare
function when you know the elements are comparable, but we don't have intersection types, so we can't require elements to beList<E>&List<Comparable<E>>
and we can't requireE extends Comparable<E>
.So, what if constructors could provide type parameters that are more restrictive than for the class itself:
Type parameters on the class name of a constructor must be valid type arguments to the class itself, and they are implicitly applied. Inside the constructor, the type parameters of the class are not in scope, they're replaced by the type parameters of the constructor. (Or, rather, all constructors have type parameters, if you don't write them, they are copied from the class, and constructors always only see their own type arguments.)
If we ever add extension static members (#723), we might also allow extension constructors.
At that point, it would likely mean that:
would be allowed as
List<int>.sumList([1, 2, 3])
andList<double>.sumList([1.5, 2.4])
, but notList<Object>.sumList(...)
.That means that we'd introduce the ability to have type-restricted constructors, but only through static extensions. We should then allow you to write the same constructors directly to avoid authors using extensions just for the added flexibility.
The text was updated successfully, but these errors were encountered: