Minimal reproducible code:
enum Foo {
a,
b;
String get name {
switch (this) {
case Foo.a: return 'A';
case Foo.b: return 'B';
}
}
}
void main() {
printEnum<Foo>(Foo.values);
}
void printEnum<T extends Enum>(List<T> list) {
for (var e in list) {
print(e.name);
}
}
The for
loop prints
a
b
But I wanted it to print
A
B
So, how do I override the name
property in the enum?
Note:
Using (e as Foo).name
will solve the issue, but I have many enums in my project, so I can't cast them like this.
Also, please don't post answers like, use toUpperCase()
, etc, because I just provided a simple example, but in real world, things are quite different.
CodePudding user response:
You cannot override the name
getter "on Enum
" because it's an extension getter, not an instance getter.
Overriding, aka. late binding, of instance members only apply to actual (virtual) instance members.
Extension members are statically resolved, so a call of .name
either hits the extension member, or it doesn't, and it depends entirely on the static type of the receiver. If you have an Enum e; ... e.name ...
then it will call the extension member, and there is absolutely no way to change that, or change what it does.
If you want to have a custom and overridable name
getter, I'd introduce an interface like
abstract class NamedEnum extends Enum {
String get name;
}
and then let all your enums implement NamedEnum
.
Then you can do (enumValue as NamedEnum).name
for any of your enums.
It won't interact with other enum
types' extension name
getter.
CodePudding user response:
Casting e
as dynamic
works, as long as you ensure that the name
property exists on the enum you are printing. Ex:
void printEnum<T extends Enum>(List<T> list) {
for (var e in list) {
print((e as dynamic).name);
}
}