Плюсы и минусы, явно устанавливающие значения поля enum

Предпочтительно ли явно задавать поля перечисления вместо того, чтобы просто определять их имена? Например. какие плюсы и минусы для Enum1 против Enum2?

Перечисление1:

enum SomeEnum
{
   Something1 = 0,
   Something2 = 1
}

Перечисление2:

enum SomeEnum
{
   Something1,
   Something2
}

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

Изменить: скажем, все значения равны 0, 1 и т. д. Они не являются отрицательными или что-то в этом роде.


person Kamarey    schedule 05.11.2009    source источник


Ответы (10)


Enum1 и Enum2 компилируются в одно и то же перечисление. Так что с точки зрения программирования разницы нет. С точки зрения обслуживания могут быть проблемы, а могут и не быть.

С одной стороны, объявление явных значений абсолютно необходимо для перечисления [Flags]; и они должны быть значениями степени 2.

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

В общем, я предпочитаю не объявлять явные значения, если сами значения не являются важными по какой-либо причине — если ваше перечисление C#, например, является оболочкой для перечисления C.

person Randolpho    schedule 05.11.2009
comment
Я задал этот вопрос в основном из соображений удобства использования и ремонтопригодности, поэтому этот ответ является наиболее близким. Спасибо. - person Kamarey; 08.11.2009
comment
Технически флаги можно автоматизировать, определив их как Val1=1, Val2=Val1<<1, Val3=Val2<<1, и т. д. Удобно добавлять значения (даже промежуточные), не беспокоясь об их вычислении. - person Nyerguds; 27.03.2019

это полезно, когда вам нужно иметь отрицательные значения

enum
{
  Error = -1,
  Success = 0,
  Something1, 
  Something2,
};
person Max    schedule 05.11.2009
comment
Отрицательные значения ничего не добавляют к перечислению. - person Randolpho; 05.11.2009
comment
@Randolpho: enum.s часто используются в API-интерфейсах для других приложений. Например: оболочка C#/.NET вокруг API данных Google. Если вы можете перечислить все возвращаемые значения, включая отрицательные значения, которые решил использовать создатель, это значительно добавляет. - person Dinah; 05.11.2009
comment
@Dinah: я знаю об этом (см. мой ответ на этой странице). А для обертывания старых C API часто требуются отрицательные значения для перечисления. Но я остаюсь при своем утверждении: отрицательные значения в перечислении не представляют реальной ценности. То же самое было и во времена Си. - person Randolpho; 05.11.2009

Вы должны использовать Enum1, если вам нужны несмежные значения.

enum Colors 
{ 
    Red = 1, 
    Green = 2, 
    Blue = 4, 
    Yellow = 8 
};

Кроме того, явное задание чисел легче читать, а добавление значения в середине не меняет другие значения.

person Robert Harvey    schedule 05.11.2009
comment
Привет, Роберт. Что вы имеете в виду, добавляя значение посередине, не меняет другие значения? - person BIDeveloper; 05.11.2009
comment
Если бы он добавил Purple = 3 в середине, значения Blue или Yellow не изменились бы. - person Chris Hamons; 05.11.2009
comment
Верно, но добавление его в конец также не повлияет на значения!? - person BIDeveloper; 05.11.2009
comment
Есть причины, по которым вам может понадобиться перечисление в определенном порядке. Я всегда указываю значения. - person Robert Harvey; 05.11.2009
comment
Привет, Роберт, я не говорю, что ты не прав! ОП спросил, каковы причины того или иного метода. Кроме желания узнать, что Red равен 1, есть другие причины? - person BIDeveloper; 05.11.2009
comment
Возможно, чтобы расставить их по алфавиту. Чтобы расположить их в логическом порядке. - person Robert Harvey; 05.11.2009
comment
Хм, я не понимаю, что вы говорите, однако, поскольку они появляются в алфавитном порядке через IntelliSense при кодировании, я до сих пор не вижу причины. - person BIDeveloper; 05.11.2009
comment
Да, я с Джимом в этом; порядок на самом деле не так уж и важен. - person Randolpho; 05.11.2009

Полезно явно устанавливать значения, если они имеют какое-то значение вне вашей программы. Например, приложение может записать файл журнала, в котором используется значение Severity, которое можно использовать для фильтрации файла журнала позже. Явная установка значений в Enum означает, что вы можете использовать Enum в своем коде (например, Critical, Error, Warning) вместо числовых значений. В файле журнала вы хотели бы, чтобы числовое значение было записано для облегчения сортировки.

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

person TLiebe    schedule 05.11.2009

Используйте пример 1, если вам действительно нужно иметь числа (т.е. вам нужно знать, что что-то2 на самом деле равно 2)

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

person BIDeveloper    schedule 05.11.2009
comment
давай тогда ... этот ответ, по-видимому, бесполезен? но почему? - person BIDeveloper; 05.11.2009
comment
Понижение, вероятно, произошло потому, что ваше утверждение, не нарушая кода, не на 100% верно. Если значение перечисления используется в вычислении и это значение перечисления изменяется, код сломается. - person Robert Harvey; 05.11.2009
comment
@Robert: ну, он сказал добавить, а не менять ... Я не вижу причин для -1 и компенсации. - person RedGlyph; 05.11.2009
comment
Добавить == изменить, если вы добавляете значение в середине, а значения не указаны явно. - person Robert Harvey; 05.11.2009

Я столкнулся с проблемами сериализации перечислений, которые не содержат значение 0, при их использовании через интерфейс веб-служб.

person Phillip Ngan    schedule 05.11.2009
comment
Просто используйте [EnumMember(Value = "EnumerantValue")] - person Randolpho; 05.11.2009
comment
Не так, как написано, но работает так: <EnumMember(Value:="EnumerantValue")> - person Randolpho; 05.11.2009

это зависит от того, что вы делаете с перечислениями. Если вы используете их с [Флагами], вы ДОЛЖНЫ установить их явно. если нет, то любой способ работает с точки зрения кодирования. однако для удобочитаемости или (как уже упоминалось) использования в ситуации с базой данных вы должны явно установить их. Еще одним соображением являются стандарты кодирования на вашем рабочем месте, а также сериализация.

person Muad'Dib    schedule 05.11.2009

Enum 1 также необходим, когда вам нужно использовать помеченные перечисления: http://weblogs.asp.net/wim/archive/2004/04/07/109095.aspx

person Kamau Malone    schedule 05.11.2009

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

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

> enum 
{
    flag1 = 1;
    flag2 = 2;
    flag3 = 4;
};

func1(flag1 | flag3);
person Tim Allman    schedule 05.11.2009
comment
Вы убрали атрибут [Flags]. Очень необходимо. - person Randolpho; 05.11.2009

Учтите также, что перечисления с целочисленной поддержкой будут иметь значение по умолчанию default(int) (или ноль), если их значение не было установлено, поэтому при использовании перечислений с неявной нумерацией может быть трудно различить значения перечисления которые не были заданы из значений перечисления, которым был преднамеренно присвоен первый вариант. Это может послужить хорошим аргументом в пользу явного присвоения целочисленных значений вашим значениям перечисления с начальным целым числом, отличным от нуля. Если, конечно, вы не сделаете свое первое значение «NotAssigned» или что-то в этом роде.

person Community    schedule 13.02.2013