Dart类型转换错误

IAm*_*aja 6 casting dart

我有一个抽象类Event和一个扩展它的具体子类调用PlaceChangeEvent.在事件监听器中,我有以下代码:

void onEvent(Event event) {
    PlaceChangeEvent pce = null;
    if(event is PlaceChangeEvent)
        pce = (PlaceChangeEvent)event;      // <== error is here
    else
        throw new Exception("Event is not a PlaceChangeEvent.");

    Place place = pce.place;

    presenterProvider.display(place);
}
Run Code Online (Sandbox Code Playgroud)

所以,如果的运行时类型eventPlaceChangeEvent,那么我需要将事件映射到该类型的,这样我可以访问它的属性.但我在类型转换上遇到编译错误,说明:

"类型"类型的值无法分配给"PlaceChangeEvent"类型的变量

我哪里出错了,我需要做些什么来解决它?

Flo*_*sch 7

在达特

  1. 倾向是隐含的.如果B是子类A,则B b = a(其中a是类的实例A)是警告自由并静默转换aB.在Java中,您需要编写B b = (B) a.

  2. 动态类型是一个始终存在的逃生舱口.如果BC不在同一层次,然后暂时分配给动态类型将使得投预警免费.

    B b = someB;
    var tmp = b;
    C c = tmp;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 人们可以使用明确的检查is.该is对象是否正确类型的检查返回true.还有一些非常简单的规则可以传播is-check类型.例如,如果isif条件内使用,则相应的分支将此信息用于类型警告.

    Object o;
    o.foo();  // warning: foo does not exist on Object.
    if (o is A) {  // assuming that A contains 'foo'.
      o.foo();  // warning-free.
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 如果类型不是预期的类型,则可以显式检查并抛出as.这种操作者在左侧是抛出null.

对于您的示例,这归结为:

没有明确的检查(1):

void onEvent(Event event) {
  // Implicit upcast. PlaceChangeEvent is subclass of Event.
  PlaceChangeEvent pce = event;
  Place place = pce.place;
  presenterProvider.display(place);
}
Run Code Online (Sandbox Code Playgroud)

使用is-check(3):

void onEvent(Event event) {
  if (event is PlaceChangeEvent) {
    // Static type system propagates type. No need for variable.
    Place place = event.place;
    presenterProvider.display(place);
  } else {
    // Note: this doesn't look like an exception, but an error.
    throw new Exception("Event is not a PlaceChangeEvent.");
  }
}
Run Code Online (Sandbox Code Playgroud)

使用as(4):

void onEvent(Event event) {
  Place place = (event as PlaceChangeEvent).place;
  presenterProvider.display(place);
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望收到PlaceChangeEvent,则只需更改参数的类型:

void onEvent(PlaceChangeEvent event) {
  Place place = event.place;
  presenterProvider.display(place);
}
Run Code Online (Sandbox Code Playgroud)

在检查模式下,这将捕获错误类型,在未检查模式下,它将在访问时抛出event.place.这通常是首选方式.


rin*_*aff 5

尝试这个:

pce = event as PlaceChangeEvent;
Run Code Online (Sandbox Code Playgroud)

  • @CalifornianAcorn - 如果案例失败,它将抛出 TypeError 异常(类型“Foo”不是“pce”的“PlaceChangeEvent”类型的子类型。 (2认同)