// Значения элементов в перечислении не обязательно должны
// быть последовательными!
enum EmpType
{
Manager = 10,
Grunt = 1,
Contractor = 100,
VicePresident = 9
}
Управление хранилищем, лежащим в основе перечисления
По умолчанию для хранения значений перечисления используется тип System.Int32 (int в языке С#); тем не менее, при желании его легко заменить. Перечисления в C# можно определять в похожей манере для любых основных системных типов (byte, short, int или long). Например, чтобы значения перечисления EmpTypeEnum хранились с применением типа byte, а не int, можно записать так:
// На этот раз для элементов EmpTypeEnum используется тип byte.
enum EmpTypeEnum : byte
{
Manager = 10,
Grunt = 1,
Contractor = 100,
VicePresident = 9
}
Изменение типа, лежащего в основе перечисления, может быть полезным при построении приложения .NET Core, которое планируется развертывать на устройствах с небольшим объемом памяти, а потому необходимо экономить память везде, где только возможно. Конечно, если в качестве типа хранилища для перечисления указан byte, то каждое значение должно входить в диапазон его допустимых значений. Например, следующая версия EmpTypeEnum приведет к ошибке на этапе компиляции, т.к. значение 999 не умещается в диапазон допустимых значений типа byte:
// Ошибка на этапе компиляции! Значение 999 слишком велико для типа byte!
enum EmpTypeEnum : byte
{
Manager = 10,
Grunt = 1,
Contractor = 100,
VicePresident = 999
}
Объявление переменных типа перечисления
После установки диапазона и типа хранилища перечисление можно использовать вместо так называемых "магических чисел". Поскольку перечисления — всего лишь определяемые пользователем типы данных, их можно применять как возвращаемые значения функций, параметры методов, локальные переменные и т.д. Предположим, что есть метод по имени AskForBonus(), который принимает в качестве единственного параметра переменную EmpTypeEnum. На основе значения входного параметра в окно консоли будет выводиться подходящий ответ на запрос о надбавке к зарплате.
Console.WriteLine("**** Fun with Enums *****");
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})
// Создать переменную типа EmpTypeEnum.
EmpTypeEnum emp = EmpTypeEnum.Contractor;
AskForBonus(emp);
Console.ReadLine();
// Перечисления как параметры.
static void AskForBonus(EmpTypeEnum e)
{
switch (e)
{
case EmpType.Manager:
Console.WriteLine("How about stock options instead?");
// He желаете ли взамен фондовые опционы?
break;
case EmpType.Grunt:
Console.WriteLine("You have got to be kidding...");
// Вы должно быть шутите...
break;
case EmpType.Contractor:
Console.WriteLine("You already get enough cash...");
// Вы уже получаете вполне достаточно...
break;
case EmpType.VicePresident:
Console.WriteLine("VERY GOOD, Sir!");
// Очень хорошо, сэр!
break;
}
}
Обратите внимание, что когда переменной enum присваивается значение, вы должны указывать перед этим значением (Grunt) имя самого перечисления (EmpTypeEnum). Из-за того, что перечисления представляют собой фиксированные наборы пар "имя-значение", установка переменной enum в значение, которое не определено прямо в перечислимом типе, не допускается:
static void ThisMethodWillNotCompile()
{
// Ошибка! SalesManager отсутствует в перечислении EmpTypeEnum!
EmpTypeEnum emp = EmpType.SalesManager;
// Ошибка! He указано имя EmpTypeEnum перед значением Grunt!
emp = Grunt;
}
Использование типа System.Enum
С перечислениями .NET Core связан один интересный аспект — они получают свою функциональность от класса System.Enum. В классе System.Enum определено множество методов, которые позволяют исследовать и трансформировать заданное перечисление. Одним из них является метод Enum.GetUnderlyingType(), который возвращает тип данных, используемый для хранения значений перечислимого типа (System.Byte в текущем объявлении EmpTypeEnum):