# DART 'ENUMERATION' (Flutter)

Enumerated types, often called *enumerations* or *enums*, are a special kind of class used to represent a fixed number of constant values.

### Declaring an enum

To declare a simple enum, you use the `enum` keyword and list some values you want to be enumerated. For example:

```dart
enum Status {
  pending,
  completed,
  rejected,
}
```

By convention, you name the enum using `PascalCase` in which you capitalize the first character of each word. Also, you use `camelCase` to name enum values.

### Using an enum

To access an enum value, you use the enum name, dot operator, and the value. For example:

```dart
var initialStatus = Status.pending;
print(initialStatus);
```

Output:

```dart
Status.pending
```

Each enum value has an `index` getter that returns the zero-based position of the value in the enum declaration.

For example, in the `Status` enum, the pending has an index of 0, the completed has an index of 1, and the rejected has an index of 2:

```dart
enum Status {
  pending,
  completed,
  rejected,
}

void main() {
  print(Status.pending.index);
  print(Status.completed.index);
  print(Status.rejected.index);
}
```

Output:

```dart
0
1
2
```

### Using enum in a switch statement

Enums work very well with the `switch` statement. For example:

```dart
enum Status {
  pending,
  completed,
  rejected,
}

void main() {
  var status = Status.completed;

  switch (status) {
    case Status.pending:
      print('The request is pending');
      break;
    case Status.completed:
      print('The request completed successfully.');
      break;
    case Status.rejected:
      print('The request faield.');
      break;
  }
}
```

Notice that if you don’t handle all of the enumerated values, you’ll get a warning. For example:

```dart
enum Status {
  pending,
  completed,
  rejected,
}

void main() {
  var status = Status.completed;

  switch (status) {
    case Status.completed:
      print('The request completed successfully.');
      break;
    case Status.rejected:
      print('The request faield.');
      break;
  }
}
```

Warning:

```dart
Missing case clause for 'pending'.
Try adding a case clause for the missing constant, or adding a default
```

## Enum class

All enums automatically extend the `Enum` class. Also, you cannot subclass, implement or mix in, or create a new instance of an enum. For example:

```dart
enum Status { pending, completed, rejected }

void main() {
  var status = Status.completed;
  print(status is Enum); // true
}
```

## Enhanced enums

Suppose that you have an enum called `OrderStatus`:

```dart
enum OrderStatus {
  open,
  confirmed,
  completed,
  cancelled,
}
```

and you want to compare an instance of the `OrderStatus` with others like this:

```dart
var status = OrderStatus.open;
if (status < OrderStatus.completed) {
  //...
}
```

You’ll get an error:

```dart
The operator '<' isn't defined for the type 'OrderStatus'.
```

To resolve this, you need to use enhanced enums. Like classes, you can define fields, methods, and const constructors with the following rules:

* Instance variables must be final. They cannot have the name `values` because it’ll cause a conflict with the autogenerated `values` getter.
    
* Generative constructors must be constant.
    
* Factory constructors can only return one of the fixed, known enum instances.
    
* Cannot override `index`, `hashCode`, the equality operator `==`.
    
* Declare all instances at the beginning of the enum. An enum must have at least one instance.
    

Note that Dart has supported enhanced enums since version 2.17.

For example:

```dart
enum OrderStatus {
  open(10),
  confirmed(20),
  completed(30),
  cancelled(40);

  final int progress;
  const OrderStatus(this.progress);

  bool operator <(OrderStatus status) => progress < status.progress;
  bool operator >(OrderStatus status) => progress > status.progress;
}

void main() {
  var status = OrderStatus.open;
  if (status < OrderStatus.completed) {
    print('The order has not completed');
  }
}
```

How it works.

First, define the `progress` as a final instance variable. By rule, it must be `final`:

```dart
final int progress;
```

Next, initialize the progress instance variable in the `const` constructor:

```dart
const OrderStatus(this.progress);
```

Then, declare constant values and initialize them with different progress values:

```dart
open(10),
confirmed(20),
completed(30),
cancelled(40);
```

After that, override the less than and greater than operators. In these methods, we compare the `progress` of one enum with another:

```dart
bool operator <(OrderStatus status) => progress < status.progress;
bool operator >(OrderStatus status) => progress > status.progress;
```

Finally, use the less-than operator (`<`) to compare values of the `OrderStatus` enum:

```dart
void main() {
  var status = OrderStatus.open;
  if (status < OrderStatus.completed) {
    print('The order has not completed');
  }
}
```

## Summary

* Use `enum` type to manage a fixed number of constants.
    

## **THANK YOU!**
