Перечисления enum в C# — объявление и использование

Перечисления (enum) позволяют задать список именованных опций для переменной. Это удобно, когда нужно хранить конечный набор значений, например дни недели. Enum делает код читабельнее и снижает вероятность ошибок. Часто для обработки таких значений используют оператор switch.
Что такое enum — простая дефиниция
Enum — именованный набор констант целочисленного значения. Каждая опция имеет числовой индекс. По умолчанию первый элемент получает значение 0, но можно задать и другое начальное значение.
Важно: enum задаёт значение и семантику (имя) одновременно. Используйте enum, когда набор вариантов фиксирован и не ожидается частых изменений.
Как объявить enum в C
В C# перечисления обычно объявляют на уровне пространства имён или внутри классов в зависимости от области видимости. Пример объявления enum в консольном приложении:
class Program
{
enum Weekday {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
static void Main(string[] args)
{
}
}Если нужно изменить начальный индекс, укажите его для первого элемента:
enum Weekday {
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}В этом примере Monday будет иметь значение 1, Tuesday — 2 и т.д.
Как получить имя и значение enum
Значение enum в C# — это целое число (индекс). Например, при объявлении с Monday = 1 значение Weekday.Friday равно 5.
- Получить строковое имя по значению можно через Enum.GetName:
string friday = Enum.GetName(typeof(Weekday), Weekday.Friday);
Console.WriteLine("Thank God it's " + friday + "!");
// Output = Thank God it's Friday!- Получить элемент по индексу — привести числу к типу enum:
Weekday tuesday = (Weekday)2;
Console.WriteLine("Today is " + tuesday);
// Output = Today is Tuesday- При выводе enum в Console.WriteLine вызывается ToString(), поэтому печатается имя, а не число:
Console.WriteLine(Weekday.Thursday + " is the new " + Weekday.Friday);
// Output = Thursday is the new Friday- Преобразовать в целое можно явным приведением:
int mondayIndex = (int)Weekday.Monday;
Console.WriteLine(mondayIndex);
// Output = 1Как сравнивать enum
Перечисления можно сравнивать операторами (==, !=, <, >, <=, >=). Сравнение идет по числовым значениям.
Weekday day1 = Weekday.Monday;
Weekday day2 = Weekday.Tuesday;
if (day1 == day2)
{
Console.WriteLine("The days are the same.");
}
else
{
Console.WriteLine("The days are different.");
}Также доступен метод Equals():
if (day1.Equals(day2))
{
Console.WriteLine("The days are the same.");
}
else
{
Console.WriteLine("The days are different.");
}Switch — удобный способ выполнить действие по каждому значению enum:
Weekday valueToCompare = Weekday.Wednesday;
switch (valueToCompare)
{
case Weekday.Monday:
Console.WriteLine("I need coffee.");
break;
case Weekday.Tuesday:
Console.WriteLine("I need coffee.");
break;
case Weekday.Wednesday:
Console.WriteLine("I need coffee.");
break;
case Weekday.Thursday:
Console.WriteLine("Thursday is the new Friday!");
break;
case Weekday.Friday:
Console.WriteLine("Thank God it's Friday!");
break;
case Weekday.Saturday:
Console.WriteLine("My favorite day!");
break;
case Weekday.Sunday:
Console.WriteLine("My other favorite day!");
break;
default:
Console.WriteLine("Invalid day of the week.");
break;
}Как перебрать все значения enum
- Enum.GetValues возвращает массив значений enum. Пример перебора с выводом индекса и имени:
foreach (Weekday day in Enum.GetValues(typeof(Weekday)))
{
Console.WriteLine((int)day); // To print the index
Console.WriteLine(day); // To print the text value
}- Enum.GetNames возвращает массив строк с именами, которые можно распарсить обратно в enum:
foreach (string name in Enum.GetNames(typeof(Weekday)))
{
int index = (int)(Weekday)Enum.Parse(typeof(Weekday), name);
Console.WriteLine(index); // To print the index
Console.WriteLine(name); // To print the text value
}Практическое применение enum
Enum полезны для повышения читаемости, ограничения допустимых значений и предотвращения «магических» чисел в коде. Часто их используют вместе со словарями, для передачи состояний в методах и сериализации/десериализации с учётом имен.
Когда enum не подходит или даёт проблемы
- Если набор опций часто меняется в рантайме (загружается из БД), enum может быть неудачным выбором — лучше использовать конфигурацию или таблицы в БД.
- Когда нужны битовые флаги для комбинирования значений — используйте [Flags] с пояснением и проверками.
- Для версионирования API изменение значений enum может привести к несовместимости; в этом случае предпочтительны строки или стабильная схема маппинга.
Важно: изменение порядковых значений enum (индексов) может нарушить сериализованные данные и совместимость.
Альтернативы и когда их применять
- Константы (const, static readonly) — подходят для отдельных значений, но не группируют набор.
- Строковые значения — удобны для внешнего API и устойчивы к изменениям индексов, но медленнее и меньше контроля типов.
- Классы со статическими экземплярами (pattern typesafe enum) — полезны, когда нужны дополнительные данные и поведение для каждого варианта.
- Флаги ([Flags]) — когда значения комбинируются побитово.
Быстрая шпаргалка (cheat sheet)
- Объявление: enum Name { A, B, C }
- Приведение числа к enum: (Name)1
- Приведение enum к числу: (int)Name.B
- Получить имя: Enum.GetName(typeof(Name), value)
- Получить значения: Enum.GetValues(typeof(Name))
- Получить имена: Enum.GetNames(typeof(Name))
- Parse из строки: (Name)Enum.Parse(typeof(Name), “A”)
Ментальные модели и эвристики
- Enum = набор валидных вариантов. Представляйте enum как «вперёд-фиксированный список опций».
- Если значение должно иметь поведение или поля — рассмотрите класс вместо enum.
- Для публичных API отдавайте предпочтение строкам или устойчивому маппингу, чтобы не ломать клиентов при рефакторинге.
Чеклист для ролей
- Для разработчика: использовать enum для ограниченных наборов; документировать значение индексов если сериализуется.
- Для тимлида: контролировать изменения enum в релизном цикле; оценивать обратную совместимость.
- Для тестировщика: добавить тесты на сериализацию/десериализацию и граничные кейсы (неизвестные значения).
Примеры тест-кейсов и критерии приёмки
- При задании корректного имени Enum.Parse возвращает соответствующий элемент.
- При приведении числу (int) возвращается ожидаемый индекс.
- При передаче неизвестного числового значения в switch — срабатывает default.
- Сериализованный enum совместим между версиями (при изменении кода тесты должны зафиксировать несовместимость).
Краткая глоссарий на 1 строку
- enum — именованный набор констант с целочисленными значениями.
- [Flags] — атрибут для побитового комбинирования значений enum.
- Enum.GetValues — возвращает все значения перечисления.
- Enum.GetNames — возвращает имена значений перечисления.
Краткое резюме
- Enum в C# упрощают код и задают ограниченный набор значений.
- Используйте приведение типов, Enum.GetName/GetValues/GetNames и switch для работы с ними.
- Оцените альтернативы, если набор меняется в рантайме или требуется расширяемость.
Важно: перед изменением значений enum проверяйте влияние на сериализацию и клиентов.
Похожие материалы
Как понять, стоит ли смотреть новый сериал
Как обойти ограничения Facebook и удобнее им пользоваться
accountsd просит доступ к login keychain: причины и исправление
Как чистить микрофон и защитить его от микробов
Микрофон не работает в CS:GO — как исправить