// На этот раз для элементов 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 *****");
// Создать переменную типа 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
):
Console.WriteLine("**** Fun with Enums *****");
...
// Вывести тип хранилища для значений перечисления.
Console.WriteLine("EmpTypeEnum uses a {0} for storage",
Enum.GetUnderlyingType(emp.GetType));
Console.ReadLine;
Метод
Enum.GetUnderlyingType
требует передачи
System.Type
в качестве первого параметра. В главе 15 будет показано, что класс
Туре
представляет описание метаданных для конкретной сущности .NET Core.
Один из возможных способов получения метаданных (как демонстрировалось ранее) предусматривает применение метода
GetType
, который является общим для всех типов в библиотеках базовых классов .NET Core. Другой подход заключается в использовании операции
typeof
языка С#. Преимущество такого способа связано с тем, что он не требует объявления переменной сущности, описание метаданных которой требуется получить:
// На этот раз для получения информации о типе используется операция typeof
Console.WriteLine("EmpTypeEnum uses a {0} for storage",
Enum.GetUnderlyingType(typeof(EmpTypeEnum)));
Динамическое обнаружение пар "имя-значение" перечисления
Кроме метода
Enum.GetUnderlyingType
все перечисления C# поддерживают метод по имени
ToString
, который возвращает строковое имя текущего значения перечисления. Ниже приведен пример:
EmpTypeEnum emp = EmpTypeEnum.Contractor;
...
// Выводит строку "emp is a Contractor."
Console.WriteLine("emp is a {0}.", emp.ToString);
Console.ReadLine;
Если интересует не имя, а значение заданной переменной перечисления, то можно просто привести ее к лежащему в основе типу хранилища, например: