我有一个抽象类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)
所以,如果的运行时类型event是PlaceChangeEvent,那么我需要将事件映射到该类型的,这样我可以访问它的属性.但我在类型转换上遇到编译错误,说明:
"类型"类型的值无法分配给"PlaceChangeEvent"类型的变量
我哪里出错了,我需要做些什么来解决它?
在达特
倾向是隐含的.如果B是子类A,则B b = a(其中a是类的实例A)是警告自由并静默转换a为B.在Java中,您需要编写B b = (B) a.
动态类型是一个始终存在的逃生舱口.如果B与C不在同一层次,然后暂时分配给动态类型将使得投预警免费.
B b = someB;
var tmp = b;
C c = tmp;
Run Code Online (Sandbox Code Playgroud)人们可以使用明确的检查is.该is对象是否正确类型的检查返回true.还有一些非常简单的规则可以传播is-check类型.例如,如果is在if条件内使用,则相应的分支将此信息用于类型警告.
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)如果类型不是预期的类型,则可以显式检查并抛出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.这通常是首选方式.
尝试这个:
pce = event as PlaceChangeEvent;
Run Code Online (Sandbox Code Playgroud)