Robin
Robin

Reputation: 115

Access field of subclassed object without casting

Given the following classes:

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];
}

I want to access someField if the current state is of type SomeState in my mapEventToState method, but the compiler doesn't allow that:

 @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'.
    }
}

If I manually create a ParentState variable, however, it works as expected:

ParentState state = SomeState(someField: 'test');

if (state is SomeState) {
   print(state.someField); // Works.
}

Also, manually casting in mapEventToState works, but that shouldn't be required:

if (state is SomeState) {
    print((state as SomeState).someField); // Works.
}

What am I missing?

Upvotes: 0

Views: 90

Answers (1)

Christopher Moore
Christopher Moore

Reputation: 17123

In your first example with the error, it seems like state is a field in the surrounding class with an auto-generated getter and setter.

However from the perspective of the analyzer, it's possible for state to also be a getter function that allows the return of a different object each time the getter is called. So on the first call to the getter in the if statement the getter could return a SomeState object, but in the if body, the getter could return a completely different object without a someField getter.

To get around this problem, you just need to create a local copy of your variable within the function and use that copy instead of the class field:

@override
Stream<ParentState> mapEventToState(
  ParentEvent event,
) async* {
  final stateCopy = state;
  if (stateCopy is SomeState) {
      print(stateCopy.someField);
  }
}

Upvotes: 1

Related Questions