Какой смысл использовать int как перечисления - PullRequest
7 голосов
/ 10 февраля 2011

Почему многие люди делают перечисления таким образом:

public enum EmployeeRole
{
  None = 0,
  Manager = 1,
  Admin = 2,
  Operator = 3
}

вместо того, чтобы просто делать:

public enum EmployeeRole
{
  None,
  Manager,
  Admin,
  Operator
}

Есть ли преимущества?

Ответы [ 6 ]

4 голосов
/ 10 февраля 2011

Есть ли преимущества?

Ремонтопригодность.Допустим, эти целочисленные значения в конечном итоге сохраняются в базе данных.Вы не хотите добавлять новое значение в перечисление в будущем и его значения изменятся, потому что вы вставляете значение способом, который сдвигает неопределенные значения.

Ясность.Откровенность это хорошая вещь.Скажем еще раз, мы читаем целые числа из базы данных из некоего устаревшего приложения.Таким образом, коды уже имеют конкретное значение, и мы хотим явно соответствовать им.Мы могли бы сказать

public enum EmployeeRole {
    None,
    Manager,
    Admin,
    Operator
}

и, возможно, это точно соответствует устаревшей спецификации, или мы могли бы сказать

public enum EmployeeRole {
    None = 0,
    Manager = 1,
    Admin = 2,
    Operator = 3
}

, и теперь легче понять, согласны ли мы сустаревшая спецификация.

2 голосов
/ 10 февраля 2011

Это полезно, когда у вас есть контракт в другом месте. Если вы храните перечисление в базе данных, вы хотите явно ввести числа, чтобы быть уверенным, что вы случайно не перенумеровали перечисление, вставив новый элемент посередине.

1 голос
/ 10 февраля 2011

Это объясняет, определяет значение, а не позволяет компилятору обрабатывать его во время компиляции. В случае, если вы предоставили, это действительно не имеет смысла, кроме как быть читаемым и хорошо определенным. Это не повредит ничему и приводит к тому же MISL, что и их явная настройка. Однако в тех случаях, когда ваши перечисления относятся к определенным значениям, которые не увеличиваются автоматически, как в приведенном выше случае, этот вид явного определения очень удобен.

public enum MyEnum
{

    First = 1,
    Second = 2,
    Eleventh = 11

}
0 голосов
/ 10 февраля 2011

Я вижу два основных преимущества:

  • Предоставление значения, которое реализуется для чего-то другого (например, значение базы данных, интервал и т. Д.).Обратите внимание, что вам не нужно указывать упорядоченные значения.Например, это могут быть 1, 23, 2 и 4.
  • Это гораздо удобнее для чтения, когда вам нужны числовые значения.
0 голосов
/ 10 февраля 2011

Например, когда вы храните значения в базе данных, рекомендуется иметь фиксированное отображение между числами и символическими значениями.Если вы не укажете числовые значения явно, компилятор будет нумеровать их последовательно, поэтому, если вы вставите новое, у вас будет несоответствие.

0 голосов
/ 10 февраля 2011

Это помогает избежать изменения этих предположительно постоянных значений только потому, что кто-то переставляет класс. Скажем, у вас есть новый сотрудник, который решает, что «Нет» должен идти в конце списка:

public enum EmployeeRole
{
  Manager,
  Admin,
  Operator,
  None
}

Ну, если бы вы только когда-либо обращались к этим значениям непосредственно из EmployeeRole. Как бы то ни было, это не так уж сложно. Но большинство перечислений, которые я видел, в какой-то момент преобразуются в целочисленные значения, когда они сохраняются в базе данных. Это означает, что все ваши «None» элементы в хранилище были просто преобразованы в «Manager».

Та же проблема возникнет, если кто-то просто вставит новую EmployeeRole между, скажем, Admin и Operator.

Другое преимущество возникает, когда вы не считаете подходящим значением по умолчанию для вашего перечисления. Например, если кто-то забыл сопоставить поле EmployeeRole в ORM, объекты, извлеченные из хранилища, всегда будут иметь роль None (0 всегда является значением по умолчанию для перечислений). В зависимости от того, как ваше программное обеспечение обрабатывает None, этот тип ошибки может оставаться не исправленным в течение некоторого времени. Но если вы сделаете это:

public enum EmployeeRole
{
  Manager = 1,
  Admin = 2,
  Operator = 3
}

... и затем, комбинируя это с отказоустойчивыми методами, вы можете быстро отлавливать ошибки, если было предоставлено недопустимое значение "0":

public RightsManager GetByEmployeeRole(EmployeeRole role)
{
    Require.That(role.IsDefined()); // throws an exception if role is not defined.
    // find the rights manager for this role.
}
...