I'm trying to implement a BLOC pattern for the Flutter project, my code is plentifully reusable, so I decide to use generic programming to implement it.
First I defined the event classes:
import 'package:flutter_bloc/flutter_bloc.dart';
abstract class AbstractSelectionEvent<T> {
final T obj;
AbstractSelectionEvent(this.obj);
}
class SelectedEvent<T> extends AbstractSelectionEvent<T> {
SelectedEvent(T obj) : super(obj);
}
class UnselectedEvent<T> extends AbstractSelectionEvent<T> {
UnselectedEvent(T obj) : super(obj);
}
class ChangeSelectionEvent<T> extends AbstractSelectionEvent<T> {
ChangeSelectionEvent(T obj) : super(obj);
}
Then the state classes:
abstract class AbstractSelectionState<T> {
final Set<T> selected;
AbstractSelectionState(this.selected);
AbstractSelectionState<T> select(T obj);
AbstractSelectionState<T> unselect(T obj);
AbstractSelectionState<T> changeSelect(T obj);
AbstractSelectionState<T> reset(T obj);
}
class SelectedState<T> extends AbstractSelectionState<T> {
SelectedState(Set<T> selected) : super(selected);
SelectedState<T> select(T obj) => SelectedState<T>(selected..add(obj));
SelectedState<T> unselect(T obj) => SelectedState<T>(selected..remove(obj));
SelectedState<T> changeSelect(T obj) =>
selected.contains(obj) ? unselect(obj) : select(obj);
SelectedState<T> reset(T obj) => SelectedState<T>(<T>{});
}
Finally, When I wrote the BLOC class I face some troubles.
abstract class SelectionBloc<
T,
E extends AbstractSelectionEvent<T>,
S extends AbstractSelectionState<T>
> extends Bloc<E, S> {
SelectionBloc(S initialState) : super(initialState) {
// ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ The first error
on<SelectedEvent<T>>((event, emit) {
// ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ The second error
emit(state.select(event.obj));
});
}
}
The first error says
'SelectedEvent<T>' doesn't conform to the bound 'E' of the type parameter 'E'.
Try using a type that is or is a subclass of 'E'.
The second error:
The argument type 'AbstractSelectionState<T>' can't be assigned to the parameter type 'S'.
For the second error, I know that select
, unselect
, changeSelect
, reset
functions return AbstractSelectionState<T>
.
And SelectionBloc
expects S
state for emit
function, which is subclass of AbstractSelectionState<T>
.
But from another side, the AbstractSelectionState<T>
class is abstract, which means that the returned value of the functions must be an instance of AbstractSelectionState<T>
subclasses.
Is this issue can be fixed?