I created a class that accepts a generic enum as one of it's parameters. However when I then go to pass in a specified enum type, it throws the error Expected a value of type '(Enum?) => void', but got one of type '(GradeLevel?) => void'
.
My classes are: Radio Group Presentable
class RadioGroupPresentable<T extends Enum> implements Presentable {
final List<T> values;
final T groupValue;
void Function(T? value) onChanged;
RadioGroupPresentable(this.values, this.groupValue, this.onChanged);
}
RadioGroup
class RadioGroup<T extends Enum> extends StatelessWidget {
final List<T> _values;
final T _groupValue;
ValueChanged<T?> onChanged;
RadioGroup(this._values, this._groupValue, this.onChanged, {super.key});
RadioGroup.fromPresentable(RadioGroupPresentable<T> p): this(p.values, p.groupValue, p.onChanged);
@override
Widget build(BuildContext context) {
print("building radio grouo");
return Column(
children: _values.map((e) {
return ListTile(
title: Text(e.name),
leading: Radio<T>(
value: e,
groupValue: _groupValue,
onChanged: onChanged,
),
);
}).toList(),
);
}
}
Enum
enum GradeLevel {
tenth, eleventh, twelfth
}
Presentable creation
RadioGroupPresentable(GradeLevel.values, GradeLevel.tenth, (value) {
if (value != null) {
gradeLevel.setValue(value, action: "Update Grade Level");
_application.gradeLevel = value;
print(value);
}
})
View (where error occurs)
case RadioGroupPresentable<GradeLevel>:
RadioGroupPresentable<GradeLevel> presentable = p as RadioGroupPresentable<GradeLevel>;
RadioGroup widget = RadioGroup.fromPresentable(presentable);
content.add(widget);
break;
I have tried to make the class generic so it would accept any enum, however it crashes when I pass it an enum.
CodePudding user response:
The issue is caused by this line:
RadioGroup widget = RadioGroup.fromPresentable(presentable);
Type inference is failing here, so this is being interpreted as RadioGroup<Enum>.fromPresentable(presentable)
rather than RadioGroup<GradeLevel>.fromPresentable(presentable)
.
When the RadioGroup.fromPresentable
structure attempts to store the onChanged
function, it finds a function that has the wrong type. It wants a function that is capable of taking an argument of any Enum
type, but the function it finds is only capable of taking arguments of the GradeLevel
type.
Remember, a function is only a subtype of another if its argument types are equally or more permissive than its supertype.
(Enum value) {} is void Function(GradeLevel);
(GradeLevel value) {} is! void Function(Enum);