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');
}
}