我创建了一个包含泛型数据类型的类。
class Buck<E> {
List<E> list;
Buck({
required this.list,
});
}
然后,我创建了一个类和一个子类:
class SomeThing {}
class SomethingOther extends SomeThing {}
我创建了一个对象Buck
,其中E
是SomeThing
类。
var buck = Buck<SomeThing>(list: List<SomeThing>.empty());
在这里,我假设buck.list
的类型是List<SomeThing>
。然后,我用List<SomethingOther>
分配它。
buck.list = List<SomethingOther>.empty();
在这一点上,没有什么不寻常的。我假设buck.list
的类型仍然是List<SomeThing>
。但是,当我尝试将SomeThing
对象添加到buck.list
时,我得到一个错误:
buck.list.add(SomeThing()); // this will be error
下面是完整的代码:
void main() {
var buck = Buck<SomeThing>(list: List<SomeThing>.empty());
buck.list = List<SomethingOther>.empty();
buck.list.add(SomeThing());
}
class Buck<E> {
List<E> list;
Buck({
required this.list,
});
}
class SomeThing {}
class SomethingOther extends SomeThing {}
为什么会出现这种情况?这是预期的行为吗?
1条答案
按热度按时间kqhtkvqz1#
如果
Derived
是Base
的子类型,则Dart将Generic<Derived>
视为Generic<Base>
的子类型。因此,Generic<Derived>
可分配给Generic<Base>
。对于大多数泛型来说,这不是问题,而且它通常提供了方便。对于集合,它可能会导致您遇到的问题。
List<Derived>
只能存储 *Derived
个元素。因此,如果代码试图添加其他Base
元素,则将List<Derived>
分配给List<Base>
实际上并不安全。真不幸
为了避免这种情况,您应该确保构造
List<Something>
,即使它是用SomethingOther
元素初始化的。例如:为了更好的保护,你可以让
Buck
创建自己的输入List
的内部副本,这样它就可以确保它总是有一个List<Something>
而不是List<SomethingOther>
:另见: