Search code examples
dartserializationenums

Converting integer to generic enum in Dart


I have an integer I want to turn into an enum in Dart. I want to do this with generics so I don't have to write the same code again and again for each possible kind of enum.

I know how to do this for one particular kind of enum, per this answer, by using the index operator [] like so

T get notQuiteGenericEnumGetter {
    int i = fromSomeplace();
    if (T == MyEnum) {
        return MyEnum.values[i] as T;
    }else if (T ==
    // tests for other sorts of enumes
}

But what I really want is this done generically so I don't need a long list of if-statements, one for each possible enum. I'd rather do something like this using generics.

T get genericEnumGetter {
    int i = fromSomeplace();
    if (T == Enum) {
        return T.values[i] as T;
    }
}

But this doesn't work if I spell enum as "enum" (undefined name), or as "Enum" (getter values isn't defined for type Type).

I also tried return (T as Enum).values[i] as T; and I'm told the getter 'values' isn't defined for the type 'Enum', which makes me wonder how MyEnum.values worked.

So I guess my question is whether the idea of converting an int to an enum without explicitly testing for the flavor of enum is hopeless, or if there's some approach that works generically for converting integers into enums.


Solution

  • What you're trying to do is not possible for multiple reasons.

    • Even for non-Enum classes, T.anything can never work because static members are not part of the class's interface in Dart. static members are essentially syntactic sugar for globals. The automatically generated values list for Enum types are no different.

    • Dart currently does not allow generic getters.

    Even if Dart did allow generic getters (or if you changed it to a normal generic function instead), you'd need to explicitly specify the Enum type name (where would it get inferred from?), at which point you might as well type MyEnum.values[i], which is only slightly more inconvenient.

    I also tried return (T as Enum).values[i] as T; and I'm told the getter 'values' isn't defined for the type 'Enum', which makes me wonder how MyEnum.values worked.

    Enum is the base type types that declared with enum. Enum itself has no values member; Enum has no values! Only the concrete types declared with enum have the synthesized values members. (Also see Where is "values" defined in a List of enum?)