#flutter #dart #inheritance #polymorphism
Вопрос:
Учитывая следующие классы:
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];
}
Я хочу получить доступ someField
, если текущее состояние соответствует типу SomeState
в моем mapEventToState
методе, но компилятор этого не разрешает:
@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.
}
Чего мне не хватает?
Ответ №1:
В вашем первом примере с ошибкой похоже state
, что это поле в окружающем классе с автоматически сгенерированным средством получения и установки.
Однако, с точки зрения анализатора, также может state
быть функция получения, которая позволяет возвращать другой объект каждый раз, когда вызывается средство получения. Таким образом, при первом вызове геттера в if
инструкции геттер может вернуть SomeState
объект, но в if
теле геттер может вернуть совершенно другой объект без someField
геттера.
Чтобы обойти эту проблему, вам просто нужно создать локальную копию вашей переменной в функции и использовать эту копию вместо поля класса:
@override
Stream<ParentState> mapEventToState(
ParentEvent event,
) async* {
final stateCopy = state;
if (stateCopy is SomeState) {
print(stateCopy.someField);
}
}
Комментарии:
1.
state
является добытчиком. Вполне логично, что сейчас это не работает. Спасибо.