问题
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
upcasts are implicit. If
Bis a subclass ofA, thenB b = a(whereais an instance of classA) is warning free and silently castsatoB. In Java you would have needed to writeB b = (B) a.the dynamic type is an always-present escape hatch. If
BandCare 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;One can do an explicit check using
is. Theischeck returns true if the object is of the right type. There are also some very simple rules that propagate is-check types. For example, ifisis used inside anifcondition, 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. }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 isnull.
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