Dart 给出未处理的异常:类型不是“值”类型的子类型

Ric*_*son 4 types casting dart

我有一个抽象类ImageUpdate。两个类,NewImageExistingImage实现ImageUpdate.

我有一个imageUpdates类型的变量List<ImageUpdate>

当我尝试将类型变量添加NewImage到列表时,出现以下错误:

Unhandled Exception: type 'NewImage' is not a subtype of type 'ExistingImage' of 'value'
Run Code Online (Sandbox Code Playgroud)

我很困惑,因为列表是 ofImageUpdate而不是ExistingImage,所以我不知道如何调试它,特别是因为 Dart 是类型安全的(我没有在任何地方使用dynamic)。

jam*_*lin 5

我怀疑您的代码类似于:

class Base {}

class Derived1 extends Base {}

class Derived2 extends Base {}

List<Base> makeList() {
  var list = [Derived1()];
  return list;
}

void main() {
  var list = makeList();
  list.add(Derived2()); // TypeError
}
Run Code Online (Sandbox Code Playgroud)

所发生的情况是该List对象最初被创建为List<Derived1>. (也就是说,list.runtimeType将类似于List<Derived1>,而不是其静态(声明)类型List<Base>。)然后,当您尝试将Derived2对象添加到时list,它将在运行时失败,因为list的实际运行时类型是List<Derived1>,它不允许Derived2元素。

这最终源于 Dart 允许从GenericClass<Derived>GenericClass<Base>ifDerived派生自 的隐式类型转换Base。这在许多情况下很有用,但也可能导致像这样的情况在运行时失败。

您可以通过明确声明您想要一个List<Base>对象来解决此问题:

List<Base> makeList() {
  var list = <Base>[Derived1()]; // Note the explicit type.
  return list;
}
Run Code Online (Sandbox Code Playgroud)

或者,如果不可能,则创建一个新List<Base>对象:

  • var list = <Base>[...makeList()];
  • var list = List<Base>.from(makeList());

(在这种特殊情况下,List.of(makeList())也可以工作,因为它会创建一个List具有静态类型的新对象,但我不会使用它,因为明确类型转换会更具可读性。)