Skip to content

Allow enum classes to have members. #1570

Closed
@lrhn

Description

@lrhn

Currently enum declarations only allow you to declare the enum values themselves.
With extension methods, you can then add methods on the enum anyway, and people are doing that.
Since enums are non-subclassable, there is no distinction between non-virtual extension methods and proper methods, so we are effectively giving people the ability to add methods to enum types, but without the convenience of being able to declare them in-line. (Also, you have to import the declaration to use the extension members, but you can use instance members directly on a returned object without importing its type).

We can even allow instance variables, but since all instances are const-created, the instance variable must be final and const-initializable, and there is no way to write a constructor, so the variable would always have the same value. We might as well disallow instance variables for now.

We currently cannot add static methods with extension methods (but we might, #723).
If we allow methods on enums, we should also allow static methods. People would be able to add their own parse or tryParse methods. There are lots of requests for that. No generative constructors allowed, factory constructors are fine (we'll just have to make sure the actual generative constructor used to create the instances has a fresh name).

(Alternatively, allow a single unnamed constructor too, with arguments passed in the enum elements as:

enum Foo {
  foo(1), bar(2), baz(42);
  final int value;
  Foo(this.value);
}

which would be rewritten to something like:

class Foo extends Enum {
  static const foo = Foo(0, "Foo.foo", 1);
  static const bar = Foo(1, "Foo.bar", 2);
  static const baz = Foo(2, "Foo.baz", 42);
  static const List<Foo> = [foo, bar, baz];
  final int value;
  Foo(int $index, String $name, this.value) : super._internal($index, $name);
}

with a superclass declared something like:

abstract class Enum<T> { 
  final int index; 
  final String _name; 
  const Enum._internal(this.index, this._name); 
  String toString() => _name;
}

This would allow users to attach values to enums, and access them through their own getters/methods as well.)

(Proposal: https://github.com/dart-lang/language/blob/master/working/0158%20-%20Enhanced%20Enum/proposal.md)

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureProposed language feature that solves one or more problems

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions