В C# перечисления являются мощным инструментом, особенно когда они используются за пределами их основной функциональности. Перечисление — это отдельный тип, состоящий из набора именованных констант, называемых списком перечислителей, объявленных с использованием ключевого слова enum. Хотя они в основном используются для объявления набора именованных констант, существуют и более продвинутые способы их использования. Эта запись в блоге направлена ​​на то, чтобы углубиться в Enums в C# и поднять вашу игру Enum на новый уровень.

Основные перечисления

По своей сути, Enum — это способ дать более понятные имена набору числовых постоянных значений.

public enum WeekDays
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

Это создает новый тип WeekDays, и мы можем объявить переменные этого типа следующим образом:

WeekDays today = WeekDays.Wednesday;

По умолчанию первый элемент Enum получает значение 0, а значение каждого последующего члена увеличивается на 1. Но это можно настроить:

public enum WeekDays
{
    Monday = 1,
    Tuesday, // 2
    Wednesday, // 3
    // ...
}

Расширенное использование перечислений

Атрибут флагов

Атрибут Flags можно использовать, когда перечисление представляет набор флагов, где каждая константа представляет бит в битовом поле.

[Flags]
public enum FilePermissions
{
    None = 0,
    Read = 1,
    Write = 2,
    Execute = 4
}

FilePermissions permissions = FilePermissions.Read | FilePermissions.Write;

Вы можете легко манипулировать этими флагами с помощью побитовых операций:

// Add Write permission
permissions |= FilePermissions.Write;

// Remove Write permission
permissions &= ~FilePermissions.Write;

// Check if Write permission is set
bool canWrite = (permissions & FilePermissions.Write) != 0;

Разбор и преобразование

Перечисления можно преобразовывать в строки и лежащие в их основе целочисленные значения.

WeekDays today = (WeekDays)Enum.Parse(typeof(WeekDays), "Friday");

string todayString = today.ToString(); // "Friday"
int todayInt = (int)today; // 5, if Monday is 1

Безопасный анализ

Метод Enum.TryParse можно использовать, чтобы избежать возникновения исключения, если строка не соответствует ни одной из именованных констант перечисления.

WeekDays day;
if (Enum.TryParse("Funday", out day))
{
    // It was a valid day
}
else
{
    // It was not a valid day
}

Итерация перечисления

Вы можете перебирать все значения перечисления, используя Enum.GetValues.

foreach (WeekDays day in Enum.GetValues(typeof(WeekDays)))
{
    Console.WriteLine(day);
}

Методы расширения

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

public static class WeekDaysExtensions
{
    public static bool IsWeekend(this WeekDays day)
    {
        return day == WeekDays.Saturday || day == WeekDays.Sunday;
    }
}

WeekDays today = WeekDays.Saturday;
Console.WriteLine(today.IsWeekend());  // True

Описательное строковое представление

Иногда строковое представление члена перечисления не подходит. Атрибут Description из System.ComponentModel может помочь.

public enum StatusCode
{
    [Description("Status is OK")]
    OK = 1,

    [Description("Status is Failed")]
    Failed = 2
}

public static class EnumExtensions
{
    public static string GetDescription(this Enum value)
    {
        var fieldInfo = value.GetType().GetField(value.ToString());
        var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

        return attributes.Length > 0 ? attributes[0].Description : value.ToString();
    }
}

StatusCode status = StatusCode.OK;
Console.WriteLine(status.GetDescription());  // Prints "Status is OK"

Большие перечисления с большим количеством флагов

Если вам нужно более 32 флагов (поскольку Enum поддерживается целым числом), вы можете использовать длинное значение, которое дает вам 64 флага.

[Flags]
public enum LargeEnum : long
{
    Flag1 = 1L << 0,
    Flag2 = 1L << 1,
    // ...
    Flag63 = 1L << 62,
    Flag64 = 1L << 63
}

Заключение

Перечисления в C# — это универсальные инструменты, которые можно использовать по-разному в соответствии с вашим конкретным вариантом использования. Понимая их расширенное использование, вы можете сделать свой код более читабельным, удобным и эффективным. Независимо от того, представляете ли вы дискретные константы, битовые флаги или что-то среднее между ними, Enums поможет вам. Удачного кодирования!