Home > Software design >  Enum Generic not allow typed enum
Enum Generic not allow typed enum

Time:11-22

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);
  • Related