Reputation: 65
So, basically I need to create restrictions of which types can be used in a Type
variable, something like this:
class ElementFilter<T extends Element> {
final Type<T> elementType; // What I want is something like Type<T>, but Type does not have a generic parameter
ElementFilter(this.elementType);
}
List<T> filterElements<T extends Element>(ElementFilter<T> element) {
return elements.where((el) => _isOfType(el, element.type)).toList();
}
filterElements(ElementFilter(ClassThatExtendsElement)); // Would work fine
filterELements(ElementFilter(String)); // Error, String does not extends Element
So it would only be possible to create ElementFilter
s with types that extend Element
. Is this possible in some way?
Upvotes: 0
Views: 246
Reputation: 71623
I highly recommend not using Type
objects at all. Ever. They're pretty useless, and if you have the type available as a type parameter, you're always better off. (The type variable can always be converted to a Type
object, but it can also be actually useful in many other ways).
Example:
class ElementFilter<T extends Element> {
bool test(Object? element) => element is T;
Iterable<T> filterElements(Iterable<Object?> elements) =>
elements.whereType<T>();
}
List<T> filterElements<T extends Element>(ElementFilter<T> filter) =>
filter.filterElements(elements).toList();
filterElements(ElementFilter<ClassThatExtendsElement>()); // Would work fine
filterElements(ElementFilter<String>()); // Error, String does not extends Element
Upvotes: 1
Reputation: 89946
I think you probably want:
/// Example usage: ElementFilter<ClassThatExtendsElement>();
class ElementFilter<T extends Element> {
final Type elementType;
ElementFilter() : elementType = T;
}
Unfortunately, there's no way to make the generic type argument non-optional. You will have to choose between having a required argument and having a compile-time constraint on the Type
argument.
Dart doesn't support algebraic types, so if you additionally want to support a finite set of types that don't derive from Element
, you could make specialized derived classes and require that clients use those instead of ElementFilter
. For example:
class StringElementFilter extends ElementFilter<Element> {
@override
final Type elementType = String;
}
(You also could create a StringElement
class that extends Element
if you want, but at least for this example, it would serve no purpose.)
Upvotes: 1