无需强制转换即可访问子类对象的字段
Access field of subclassed object without casting
给出以下 类:
abstract class ParentState extends Equatable {
const SomeState();
}
class SomeState extends ParentState {
const SomeState({required this.someField});
final String someField;
@override
List<Object> get props => [someField];
}
如果我的 mapEventToState
方法中的当前状态是 SomeState
类型,我想访问 someField
,但编译器不允许这样做:
@override
Stream<ParentState> mapEventToState(
ParentEvent event,
) async* {
if (state is SomeState) {
print(state.someField); // Error: The getter 'someField' isn't defined for the type 'ParentState'.
}
}
但是,如果我手动创建一个 ParentState
变量,它会按预期工作:
ParentState state = SomeState(someField: 'test');
if (state is SomeState) {
print(state.someField); // Works.
}
此外,在 mapEventToState
中手动投射是可行的,但这不是必需的:
if (state is SomeState) {
print((state as SomeState).someField); // Works.
}
我错过了什么?
在您的第一个错误示例中,state
似乎是 class 周围的一个字段,带有自动生成的 getter 和 setter。
然而,从分析器的角度来看,state
也可能是一个 getter 函数,允许 不同的 [=24] 的 return =] 对象,每次 getter 被调用。因此,在 if
语句中第一次调用 getter 时,getter 可以 return 一个 SomeState
对象,但在 if
主体中, getter 可以 return 一个没有 someField
getter.
的完全不同的对象
要解决此问题,您只需在函数内创建变量的本地副本并使用该副本而不是 class 字段:
@override
Stream<ParentState> mapEventToState(
ParentEvent event,
) async* {
final stateCopy = state;
if (stateCopy is SomeState) {
print(stateCopy.someField);
}
}
给出以下 类:
abstract class ParentState extends Equatable {
const SomeState();
}
class SomeState extends ParentState {
const SomeState({required this.someField});
final String someField;
@override
List<Object> get props => [someField];
}
如果我的 mapEventToState
方法中的当前状态是 SomeState
类型,我想访问 someField
,但编译器不允许这样做:
@override
Stream<ParentState> mapEventToState(
ParentEvent event,
) async* {
if (state is SomeState) {
print(state.someField); // Error: The getter 'someField' isn't defined for the type 'ParentState'.
}
}
但是,如果我手动创建一个 ParentState
变量,它会按预期工作:
ParentState state = SomeState(someField: 'test');
if (state is SomeState) {
print(state.someField); // Works.
}
此外,在 mapEventToState
中手动投射是可行的,但这不是必需的:
if (state is SomeState) {
print((state as SomeState).someField); // Works.
}
我错过了什么?
在您的第一个错误示例中,state
似乎是 class 周围的一个字段,带有自动生成的 getter 和 setter。
然而,从分析器的角度来看,state
也可能是一个 getter 函数,允许 不同的 [=24] 的 return =] 对象,每次 getter 被调用。因此,在 if
语句中第一次调用 getter 时,getter 可以 return 一个 SomeState
对象,但在 if
主体中, getter 可以 return 一个没有 someField
getter.
要解决此问题,您只需在函数内创建变量的本地副本并使用该副本而不是 class 字段:
@override
Stream<ParentState> mapEventToState(
ParentEvent event,
) async* {
final stateCopy = state;
if (stateCopy is SomeState) {
print(stateCopy.someField);
}
}