For completeness, a switch over the values of an enum must either address each value in the enum or contain
a default case. switch statements that are not over enum must end with a default case. This
exhaustiveness is enforced by compiler. However, in the code there might be other enum-like classes which are not enums according to compiler, but the
switch over its constants was intended to be exhaustive.
This rule with raise an issue when switch over such enum-like classes doesn’t cover all cases.
Enum-like classes are classes that:
- are defined as non-abstract
- have only one private non-factory constructor
- have two or more static const fields whose type is the enclosing class
- no subclasses of the class is in the defining library
Noncompliant code example
class MyEnum {
final int i;
const EnumLike._(this.i);
static const a = MyEnum._(1);
static const b = MyEnum._(2);
static const c = MyEnum._(3);
}
void foo(MyEnum e) {
switch(e) { // Noncompliant, case 'b' is missing
case MyEnum.a:
print('a');
case MyEnum.b:
print('b');
}
}
Compliant solution
class MyEnum {
final int i;
const EnumLike._(this.i);
static const a = MyEnum._(1);
static const b = MyEnum._(2);
static const c = MyEnum._(3);
}
void foo(MyEnum e) {
switch(e) {
case MyEnum.a:
print('a');
case MyEnum.b:
print('b');
case MyEnum.c:
print('c');
}
}
or
class MyEnum {
final int i;
const EnumLike._(this.i);
static const a = MyEnum._(1);
static const b = MyEnum._(2);
static const c = MyEnum._(3);
}
void foo(MyEnum e) {
switch(e) {
case MyEnum.a:
print('a');
break;
case MyEnum.b:
print('b');
break;
default:
print('default');
}
}