Home > Back-end >  How to override enum's "name" property?
How to override enum's "name" property?

Time:11-10

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);
  }
}
  •  Tags:  
  • dart
  • Related