Dart - Casting List<SuperType> to List<SubType> using generics
In Dart (and indeed in many languages) generics screws with the concept of inheritance. You would think that if Bar
inherits from Foo
, that List<Bar>
would also be castable to List<Foo>
.
This is not actually going to be the case because of how generics work. When you have a generic class, every time you use that class with a different type, that type is treated as a completely separate class. This is because when the compiler compiles those types, class MyGenericType<Foo> extends BaseClass
and class MyGenericType<Bar> extends BaseClass
are basically converted to something like class MyGenericType_Foo extends BaseClass
and class MyGenericType_Bar extends BaseClass
.
Do you see the problem? MyGenericType_Foo
and MyGenericType_Bar
are not descendants of one another. They are siblings of each other, both extending from BaseClass
. This is why when you try to convert a List<Entity>
to List<Vehicle>
, the cast doesn't work because they are sibling types, not a supertype and subtype.
With all this being said, while you cannot directly cast one generic type to another based on the relationship of the generic type parameter, in the case of List
there is a way to convert one List
type to another: the cast
method.
List<Entity> entityList = <Entity>[...];List<Vehicle> vehicleList = entityList.cast<Vehicle>(); // This cast will work
One thing to note though, if you are casting from a supertype generic to a sub-type generic and not all the elements of the list are that new type, this cast will throw an error.