Пытаюсь ликвидировать пробел в знаниях. Некоторые коллеги почему-то против применения enum'ов в C#. Почему - всё время какие-то маловразумительные ответы или просто "почитай". Пытался почитать - ничего интересного не нашел. По мне так одни плюсы. Например, для идентификации единиц измерения в вычислительных программах очень удобно и наглядно.
Так чем же плох enum?
Подозреваю, что enum плох на уровне IL. Но копать так глубоко пока нет знаний.
Oxoron: например, если из enum нужно делать строку и формат строки не позволяет использовать имена элементов перечисления. В таких случаях придется делать дополнительные методы преобразования элементов перечисления в строки. Чтобы не делать, проще использовать константы. Из последнего, могу вспомнить вот такой пример, где я решил использовать константы, чтобы не городить лишних методов. Хотя программистам, которые будут использовать код, это может доставить определенные неудобства, потребуется больше знаний, с перечислением было бы удобней. Но с другой стороны, им (программистам) придется лезть в глубь кода и, без соответствующих знаний, наличие удобных enum-ов вряд ли чем-то поможет, а вот лишний метод или лес условий, напротив, может усложнить разбор кода. В данном случае, это нижний уровень, на верхнем программисты с этими константами не встретятся.
Еще вариант, когда неизвестно, какие значения могут быть. Чтобы не ограничивать перечислениями, удобней использовать константы. Если использовать перечисления, то код может получиться совсем сложным, бесполезно сложным.
В случае с публичными проектами, константы упрощают процесс сохранения обратной совместимости между различными версиями продукта. Например, если изначально использовать перечисление, а потом вдруг выяснится, что объект, для которого создано перечисление, может иметь абсолютно любые значения, то придется заменять перечисление. Это будет сложно сделать. Потребуется делать большие перестановки в коде и при этом нужно будет сохранять совместимость со старыми версиями продукта и, что не мало важно, удобство использования (кода). Конечно, можно повесить «мягкий» Obsolete и сделать перегрузку методов, если это возможно, а потом удалить мусор через пару десятков версий. Или превратить перечисление в класс с константами и сделать из него псевдо-enum. Или вообще забить на всё и выпустить абсолютно новую серию продукта; или, что еще хуже, переделать все под старшей версий и потом сказать, что так и был. Кому это понравится? :-) С константами такие ошибки исключены, ну разве что с типами данных можно прогадать.
Перечисления нужно использовать в местах, где точно известно, что кроме Male и Female никого больше быть не может, а если и может, то их количество несущественно. Ну и еще для битовых значений, если это уместно. В глубинах кода, куда простой смертный программист не сунется, использование обычных констант позволит сохранить хорошее соотношение гибкости и удобства использования.
В небольших локальных проектах разницы никакой нет, что использовать. Ошибки проектирования проще будет исправить, т.к. не нужно думать о других людях, и последствий от этого никаких не будет.
Хотя нет, пока писал, пришел к потенциально опасной фишке перечислений – автоматическая индексация. Если не контролировать это, то можно получить серьезные логические ошибки при изменении структуры перечислений (например, если добавить элемент в начало или середину). Хотя сам никогда не рассматривал это как проблему. Обычно, если требуется запись значений перечислений, например, в базу в виде чисел, то я жестко определяю правила, проставляю значения вручную и пишу инструкцию, как это делать. В коде всегда стараюсь использовать элементы перечисления из перечислений, а не их числовые значения. Но не факт, что в большом проекте, где много людей, все будут делать аналогично.
Вот пример: public enum Sex { Male, Female }
Кто-нибудь может написать такой код, полагая, что ноль – это Male:
if (sex == 0)
{
return "Мужик!";
}
else
{
return "Нет, не мужик";
}
А потом, бац: public enum Sex { None, Male, Female }
И всё! Мужик больше не мужик :-) Пока заметят проблему, может много чего произойти (в коде и данных).
Если не секрет, а какая альтернатива? Байты использовать (инты)?
Могут возникнуть заморочки при изменениях кода, когда пары Строковое обозначение - байтовое значения меняются, но это редкость и лечится обязательной простановкой числовых значений при объявлении enum-а.