Что такое enum (перечисление) в C#?

«Что такое enum (перечисление) в C#?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

enum (перечисление) в C# — это значимый тип данных (value type), который определяет набор именованных целочисленных констант. Он используется для создания типов с фиксированным набором допустимых значений, что делает код более читаемым и безопасным.

Базовый синтаксис и поведение:

// По умолчанию значения начинаются с 0 и увеличиваются на 1
enum Status
{
    Pending,    // 0
    Active,     // 1
    Inactive,   // 2
    Deleted     // 3
}

// Можно явно задавать значения
enum HttpStatusCode
{
    OK = 200,
    BadRequest = 400,
    NotFound = 404,
    InternalServerError = 500
}

// Использование
Status currentStatus = Status.Active;
Console.WriteLine(currentStatus); // Выведет: "Active"
Console.WriteLine((int)currentStatus); // Выведет: 1

Продвинутые возможности:

  1. Флаги (битовые перечисления): Используются, когда значения могут комбинироваться.

    [Flags]
    enum Permissions
    {
        None = 0,
        Read = 1,    // 2^0
        Write = 2,   // 2^1
        Execute = 4, // 2^2
        All = Read | Write | Execute // Комбинация
    }
    
    Permissions userPerms = Permissions.Read | Permissions.Write;
    Console.WriteLine(userPerms); // Выведет: "Read, Write"
    bool canWrite = userPerms.HasFlag(Permissions.Write); // true
  2. Базовый тип: По умолчанию int, но можно использовать другие целочисленные типы (byte, short, long и т.д.).

    enum SmallEnum : byte { Value1, Value2 }
  3. Преобразования:

    // Из строки в enum (с обработкой ошибок)
    if (Enum.TryParse<Status>("Active", out Status parsedStatus))
    {
        // Успешно
    }
    // Получение всех значений или имен
    var allValues = Enum.GetValues(typeof(Status));
    var allNames = Enum.GetNames(typeof(Status));

Практические рекомендации:

  • Используйте enum вместо "магических чисел" для повышения читаемости.
  • Для флагов всегда используйте атрибут [Flags] и задавайте значения степенями двойки.
  • Проверяйте допустимость значений при получении enum извне (например, из БД или API) с помощью Enum.IsDefined.
  • Рассмотрите использование switch выражения с enum для exhaustive checking (проверки на полноту покрытия всех случаев).