Dart类型转换错误

时间:2013-12-31 15:47:07

标签: 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);
}

因此,如果event的运行时类型为PlaceChangeEvent,那么我需要将事件转换为该类型,以便我可以访问其属性。但是我在类型转换上遇到编译器错误,说明:

  

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

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

2 个答案:

答案 0 :(得分:7)

在Dart中

  1. 向上倾斜是隐含的。如果BA的子类,那么B b = a(其中a是类A的实例)会自动警告并静默转换{{1}到a。在Java中,您需要编写B

  2. 动态类型是一个始终存在的逃生舱口。如果B b = (B) aB不在同一层次结构中,则暂时分配给动态类型将使投射无警告。

    C
  3. 可以使用B b = someB; var tmp = b; C c = tmp; 进行明确检查。如果对象属于正确类型,则is检查返回true。还有一些非常简单的规则可以传播is-check类型。例如,如果在is条件中使用is,则相应的分支将此信息用于类型警告。

    if
  4. 如果类型不是具有Object o; o.foo(); // warning: foo does not exist on Object. if (o is A) { // assuming that A contains 'foo'. o.foo(); // warning-free. } 的预期类型,则可以显式检查并抛出。当左侧为as时,此运算符抛出。

  5. 对于你的例子,归结为:

    没有明确的检查(1):

    null

    使用is-check(3):

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

    使用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."); } } (4):

    as

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

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

    在检查模式下,这将捕获错误类型,在未检查模式下,它将在访问void onEvent(PlaceChangeEvent event) { Place place = event.place; presenterProvider.display(place); } 时抛出。这通常是首选方式。

答案 1 :(得分:4)

试试这个:

pce = event as PlaceChangeEvent;