Где должны юзаться enum'ы? Для чего их обычно используют?

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

В общем, я в замешательстве. Буду благодарен любой помощи!


Ответы (1 шт):

Автор решения: aepot

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

Например.

const number = 42;
int i = number;
int j = number;

При компиляции преобразуется просто в

int i = 42;
int j = 42;

То есть, в литералы.

Совершенно то же самое с перечислением.

enum Number
{
    First = 42,
    Second = 123
}

Number i = Number.First;
Number j = Number.Second;

По умолчанию Number неявно наследует int и может быть явно преобразован в этот тип. Можете явно написать enum Number : int, и от этого совершенно ничего не поменяется.

Поэтому откомпилированный код логически будет выглядеть так

int i = 42;
int j = 123;

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

Если интересно, а что за числа вот здесь

enum Value
{
    First, Second
}

То синтаксически, это эквивалент вот такой конструкции

enum Value : int
{
    First = 0,
    Second = 1
}

То есть опять везде числа, константы. Не даром вы не можете создать перечисление из строк.

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

Далее, есть случаи, когда нужно работать с флагами. Например, есть файл, его можно читать и писать

[Flags]
enum Permission
{
    None = 0,
    Read = 1,
    Write = 2,
    ReadWrite = Read | Write
}

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

Permission access = Permission.ReadWrite;
if (access.HasFlag(Permission.Read))
{
    // ...
}

Без использования перечисления это выглядело бы вот так

int access = 3;
if ((access & 1) != 0)
{
    // ...
}

Согласитесь, код с использованием перечисления выглядит понятнее?

Конечно, это не полный список ситуаций, где перечисления использовать удобно, но основной смысл где-то в этом. Главное понять, что перечисление - это не коллекция как сущность, а просто некий набор констант.

→ Ссылка