Код
#Руководства

Перечисления в C#: как правильно использовать enum

В C# есть много крутых инструментов, которые позволяют улучшить любой код. Один из них — enum. Давайте разберёмся, что это и как с ним работать.

 vlada_maestro / shutterstock

Списки перечисления (или enum) сокращают код и улучшают его читаемость. В этой статье мы создадим enum и научимся применять его эффективно.

Что такое enum в C#

Это список однотипных значений: цветов, состояний, способов выравнивания и так далее. Например, в C# существует встроенный список цветов:

//Эта надпись будет белого цвета
Console.WriteLine("Hello, World!");
 
//Указываем для текста синий цвет из списка ConsoleColor
Console.ForegroundColor = ConsoleColor.Blue;
 
//При конвертации в строку выводится идентификатор цвета
Console.WriteLine($"Color changed to {Console.ForegroundColor}");
 
//При конвертации в число - значение
Console.WriteLine($"Color code: {(int)Console.ForegroundColor}");

То есть нам не нужно вручную вводить код цвета — вместо этого мы просто выбираем значение из заранее составленного списка.

В самом enum тоже не хранится код цвета. Цифра 9 на примере выше — это индекс элемента в списке. Логика изменения цвета в нашем случае примерно такая:

//Программа проверяет, какой цвет выбран
if(ForegroundColor == ConsoleColor.Blue)
{
   //Далее программа определяет RGB-код синего цвета
   color = new Color(0, 0, 255);
}
 
//Вывод переданного текста в новом цвете
WriteLine(text, color);

Как создать enum в C#

Создайте отдельный файл и назовите его так, чтобы понять, какой это список. Например, Direction.cs:

public enum Direction
{
   North, //0
   South, //1
   East, //2
   West, //3
   None //4
}

После объявления нового enum он используется как тип данных:

Direction d = Direction.North;

Вы можете указать и какие-то собственные значения для элементов. Например, коды ответа веб-сервера:

public enum Response
{
   OK = 200,
 
   Forbidden = 403,
   NotFound = 404,
 
   InternalServerError = 500,
   BadGateway = 502
}

По умолчанию тип значения — int, но он изменяется на любой другой целочисленный тип:

public enum Days : byte
{
   Monday,
   Tuesday,
   Wednesday,
   Thursday,
   Friday,
   Saturday,
   Sunday
}

Как использовать enum в C#

Самый простой пример — конструкции if и switch.

int y = 0;
int x = 0;
 
while(true)
{
   Console.Clear();
   Console.WriteLine($"Your position: [{x} , {y}]");
   Console.WriteLine("Choose direction: ");
 
   //Выводим все значения из Direction
   foreach(Direction d in Enum.GetValues(typeof(Direction)))
   {
       Console.WriteLine($"{(int)d} - {d}");
   }
 
   int c = Convert.ToInt32(Console.ReadLine());
 
   //Такая проверка намного проще читается, чем если бы использовались просто числа
   switch((Direction)c)
   {
       case Direction.North:
           y++;
           break;
      
       case Direction.South:
           y--;
           break;
      
       case Direction.East:
           x++;
           break;
      
       case Direction.West:
           x--;
           break;
   }
}

Вот результат работы такой программы:

Также вы можете использовать enum вместе с полиморфизмом.

//Легко читается без каких-либо комментариев
item.Set(ItemType.Food);
item.Set(ItemState.InInventory);
 
//Длинные названия методов, непонятные аргументы
item.SetType(false, false, true);
item.SetState(false, true, false);
 
//Использование аксессоров упрощает изменение значений, но не решает проблему с непонятными аргументами в конструкторе
item.IsFood = true;
item.IsInInventory = true;

Таким образом вы получите код, который очень быстро читается. И теперь не нужно думать, какой метод использовать, — благодаря полиморфизму всё выглядит почти как человеческая речь: set item type — Food (указать тип предмета — Еда).

Другая хорошая практика — использовать enum в качестве возвращаемого типа для методов, в которых ошибка может произойти по разным причинам. Например, отправка данных на сервер.

public Response Send(string data)
{
   if(string.IsNullOrEmpty(data))
   {
       return Response.EmptyData;
   }
   else if(trySend(data))
   {
       return Response.Success;
   }
   else
   {
       return Response.Error;
   }
}

Этот метод возвращает три сообщения в зависимости от ситуации:

  • Попытка отправить пустой запрос.
  • Успешная отправка запроса.
  • Неизвестная ошибка.

Конечно, допустимо куда больше вариантов: от ошибки базы данных до превышения времени ожидания.

Как enum помогает улучшить читаемость

Представим, что у нас есть класс Item со следующими полями:

  • id — идентификатор;
  • name — название;
  • isWeapon — булево значение, которое говорит, является ли предмет оружием.

Все эти значения передаются объекту через конструктор, поэтому инициализация выглядит так:

Item item = new Item(1, "Sword", true);

Без enum со временем вы забудете, за что отвечает третий аргумент, и вам придётся каждый раз проверять реализацию класса, чтобы освежить память. Или вы добавите новые типы предметов, из-за чего таких аргументов (isArmor, isPotion) станет ещё больше:

Item item = new Item(1, "Potion", false, false, true);

Избежать таких неприятных моментов как раз и помогает enum: создайте перечисление ItemType и передавайте в конструктор его.

Item item = new Item(1, "Potion", ItemType.Potion);

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

Заключение

C# — это мощный и красивый язык, который даёт разработчикам большие возможности, позволяя писать почти человеческим языком. Списки перечислений — лишь одна из таких вещей. Ещё есть лямбда-функции, делегаты, ООП и многое другое.

Проверьте свой английский. Бесплатно ➞
Нескучные задания: small talk, поиск выдуманных слов — и не только. Подробный фидбэк от преподавателя + персональный план по повышению уровня.
Пройти тест
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована