I'm trying to create list of generic typed class from mixed-type list.
It works, but the problem is each Data
instance type is dynamic
.
class Data<T> {
final T value;
const Data(this.value);
}
final List<dynamic> bases = [...];
final List<Data> data = bases.map((b) {
return Data(b);
}).toList();
Attempt #2
class Data<T> {
final T value;
const Data(this.value);
}
final List<dynamic> bases = [...];
final List<Data> data = bases.map((b) {
final Type T = b.runtimeType;
return Data<T>(b);
}).toList(); // List<Data<dynamic>>
But it fails, due to: The name 'T' isn't a type so it can't be used as a type argument. Try correcting the name to an existing type, or defining a type named
CodePudding user response:
Generic type parameters must be known statically (i.e., at compile-time). If you start off with a heterogeneous List<dynamic>
, then the static type of each element is dynamic
, and therefore when you construct a Data
object from that element, it will be Data<dynamic>
.
If your heterogeneous list has a limited number of types, you could do:
var data = <Data<dynamic>>[];
for (var b in bases) {
if (b is Foo) {
var d = Data(b); // `d` is of type `Data<Foo>`
data.add(d);
} else if (b is Bar) {
var d = Data(b); // `d` is of type `Data<Bar>`
data.add(d);
} else {
throw UnimplementedError('Unrecognized type: ${b.runtimeType}');
}
}
(Note that if you do data.add(Data(b))
in the above, the Data
object will be constructed as Data<dynamic>
because the generic type parameter will be inferred from data
(of type List<Data<dynamic>>
) instead of from b
.)
Otherwise what you want isn't really possible.