Dart typecasting error

ぐ巨炮叔叔 提交于 2020-05-29 02:39:13

问题


I have an abstract class Event and a concrete subclass that extends it called PlaceChangeEvent. Inside an event listener, I have the following code:

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);
}

So if the runtime type of event is PlaceChangeEvent, then I need to cast the event to that type so that I can access its properties. But I'm getting a compiler error on the typecast, stating:

A value of type 'Type' cannot be assigned to a variable of type 'PlaceChangeEvent'

Where am I going wrong, and what do I need to do to fix it?


回答1:


In Dart

  1. upcasts are implicit. If B is a subclass of A, then B b = a (where a is an instance of class A) is warning free and silently casts a to B. In Java you would have needed to write B b = (B) a.

  2. the dynamic type is an always-present escape hatch. If B and C are not in the same hierarchy, then temporarily assigning to the dynamic type will make the cast warning-free.

    B b = someB;
    var tmp = b;
    C c = tmp;
    
  3. One can do an explicit check using is. The is check returns true if the object is of the right type. There are also some very simple rules that propagate is-check types. For example, if is is used inside an if condition, then the corresponding branch uses this information for type-warnings.

    Object o;
    o.foo();  // warning: foo does not exist on Object.
    if (o is A) {  // assuming that A contains 'foo'.
      o.foo();  // warning-free.
    }
    
  4. One can explicitly check and throw if a type is not the expected one with as. This operator does not throw when the left-hand side is null.

For your example this boils down to:

No explicit check (1):

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

With an 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.");
  }
}

Using as (4):

void onEvent(Event event) {
  Place place = (event as PlaceChangeEvent).place;
  presenterProvider.display(place);
}

Alternatively, if you expect to receive a PlaceChangeEvent, you should simply change the type of the argument:

void onEvent(PlaceChangeEvent event) {
  Place place = event.place;
  presenterProvider.display(place);
}

In checked mode this will catch bad types, and in unchecked mode it will throw when accessing event.place. This is generally the preferred way.




回答2:


Try this:

pce = event as PlaceChangeEvent;


来源:https://stackoverflow.com/questions/20859702/dart-typecasting-error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!