Где должны юзаться enum'ы? Для чего их обычно используют?
Вопрос возможно звучит глупо, но... Я немного не понимаю какова концепция enum, где их стоит применять, а где стоит воздержаться, из всего что я понял, это то что enum может хранить в себе последовательность констант. Но почему нельзя сделать просто коллекцию?
В общем, я в замешательстве. Буду благодарен любой помощи!
Ответы (1 шт):
Любая коллекция, даже массив - это объект, под него требуется выделение памяти в рантайме. Что касается констант - они закладываются в момент компиляции и могут компилятором вшиваться даже в сам код.
Например.
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)
{
// ...
}
Согласитесь, код с использованием перечисления выглядит понятнее?
Конечно, это не полный список ситуаций, где перечисления использовать удобно, но основной смысл где-то в этом. Главное понять, что перечисление - это не коллекция как сущность, а просто некий набор констант.