Преимущества использования перечислений перед непосредственным использованием целочисленных типов? - PullRequest
8 голосов
/ 14 сентября 2010

1) Мне известны следующие преимущества:

  • они повышают уровень абстракции, поскольку вы сразу видите, что представляют собой основные интегральные значения.

  • Вы можете использовать их вместо магических чисел, что делает код более понятным

  • Они также ограничивают значения, которые может иметь переменная enum, и при этом делаютприложение безопаснее, поскольку программисты знают, какие значения допустимы для переменной, поэтому я предполагаю, что они как бы обеспечивают безопасность типов

Есть ли какие-либо другие преимущества, которые они предоставляют по сравнению с непосредственным использованием интегральных значений?

2) Почему они используют интегралы в качестве базового типа, а не строки?

спасибо

Ответы [ 5 ]

8 голосов
/ 14 сентября 2010

Вы перечислили множество основных причин, по которым перечисления предпочтительнее целочисленных типов.

  • Именованные константы безопаснее и более читаемы, чем магические числа

  • Перечисления описывают программистам, для чего они.Интегральные значения не делают.

  • Естественно ограничивая набор значений, которые могут быть переданы. (У вас есть верхушка айсберга безопасности типов ... но посмотрите глубже...)

Вы также можете добавить:

  • Значительно увеличена безопасность типов.Если вы принимаете 'int', то любое int может быть передано. Если вы принимаете VehicleType, тогда может быть передан только VehicleType. Я не просто говорю о ком-то, передающем 6, когда наибольшее допустимое число равно 5.Я имею в виду, что если вы передадите FuelType.Unleaded функции, которая думает, что это означает VehicleType.Aeroplane?С перечислениями компилятор скажет вам, что вы идиот.Интегральный тип говорит: «Да, со мной все в порядке», и ваша программа демонстрирует действительно странное поведение, которое может быть чрезвычайно трудно отследить.

  • Более простой рефакторинг.Как и с любыми магическими константами, если вы передадите значение 5 в сотне мест в вашей программе, у вас возникнут проблемы, если вы решите изменить значение 5, чтобы иметь другое значение.С помощью enum (если у вас нет проблем с двоичной обратной совместимостью), вы можете изменить базовые значения.Вы также можете изменить базовый тип перечисления, если хотите (byte -> int -> long) без необходимости делать что-то большее, чем перекомпиляция клиентского кода.

  • Битовые поля очень многолегче работать, когда биты и маски могут быть названы.И если вы добавляете новые биты, вы часто можете упорядочить вещи так, чтобы простое обновление связанных масок позволило большей части вашего существующего кода идеально обрабатывать новые битовые поля без необходимости переписывать их с нуля.

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

  • Все понимают, почему константы хороши в коде.Перечисления просто дают вам возможность объединить группу связанных констант.Вы можете сделать то же самое в более грязной манере, используя пространство имен consts.

  • Использование enum для параметра вместо bool не только делает код самодокументируемым, читаемым именее подвержен ошибкам.Кроме того, гораздо проще добавить третий вариант, если вы понимаете, что двух вариантов недостаточно.

Как и во всех инструментах, перечисления могут использоваться неправильно.Просто используйте их там, где они имеют смысл.

2) Зачем использовать байты или целые числа вместо строк?Просто они маленькие и эффективные.

5 голосов
/ 14 сентября 2010

Я бы предположил, что они требуют базовых целочисленных типов для обеспечения простоты сравнения и более легкой поддержки битовых флагов.Без этого ограничения мы, или компилятор, или среда выполнения, вероятно, должны были бы прибегнуть к некоторой нечеткости, чтобы делать такие вещи, как комбинации - или мы попали бы в ситуацию, когда - как вы говорите - мы не должны заботиться о базовом типе (точка абстракции), и все же, когда мы пытаемся сказать A | B, мы получаем ошибку времени выполнения, потому что мы использовали базовый тип, который не способен к этому типу операции.

2 голосов
/ 14 сентября 2010

Одно преимущество - это когда вы хотите использовать enum в качестве флага.

Итак, если вы определите перечисление следующим образом:

[Flags]
public enum TestEnum{ A, B, C, D };

Тогда, если у вас есть метод, который принимает экземплярTestEnum в качестве переменной, вы можете объединить значения из перечисления, так что вы можете отправить, например, A | B | C в качестве параметра для метода.Затем внутри метода вы можете проверить параметр следующим образом:

if ((paramname & TestEnum.A) > 0) 
{
  //do things related to A
}
if ((paramname & TestEnum.B) > 0) 
{
  //do things related to B
}
//same for C and D

Кроме того, я думаю, что упомянутые вами причины достаточно хороши для использования перечислений.

Также относительно комментария, что вы можете принудительно ввести неправильное значение в перечисление с кодом, подобным этому (TestEnum)500;, это трудно сделать, если вы не хотите нарушать свой код.

Дело в том, чтозначение 0 для перечисления должно быть значением по умолчанию, или в случае флагов «отсутствие всех других флажков» очень важно, так как строка TestEnum myenum будет указывать myenum как 0 независимо от того, определено ли какое-либо значение перечисления для0 или нет.

1 голос
/ 15 сентября 2010

Основным преимуществом enum является то, что константы можно ссылаться последовательным, выразительным и безопасным для типов способом.Разумеется, удобочитаемость - это главное преимущество использования перечисления.

Другое преимущество состоит в том, что перечисляемые константы генерируются автоматически компилятором.
Например, если у вас был перечислимый тип константы для кодов ошибок, которые могли быв вашей программе определение enum может выглядеть примерно так: enum Error_Code {OUT_OF_MEMORY, FILE_NOT_FOUND};OUT_OF_MEMORY автоматически присваивает компилятору значение 0 (ноль), потому что оно появляется первым в определении .FILE_NOT_FOUND, равном 1, и так далее.Если вы хотите приблизиться к тому же примеру, используя символические константы или магические числа, вы напишите гораздо больше кода, чтобы сделать то же самое.

1 голос
/ 14 сентября 2010

Вы также можете анализировать Enum из строкового представления.Вы можете получить эту строку из источника данных или пользовательской записи.

Я думаю, что вы продали меня в Enums за "магические числа".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...