Найти в Дзене

Тип enum в C#

Тип enum
Система типов .NET состоит из классов, структур, перечислений, интерфейсов и делегатов. Чтобы начать исследование таких типов, рассмотрим роль перечисления (enum), создал новый проект консольного приложения.
На заметку! Не путайте термины перечисление и перечислитель; они обозначают совершенно разные концепции. Перечисление - специальный тип данных, состоящих их пар "имя-значение".
Оглавление

Тип enum

Система типов .NET состоит из классов, структур, перечислений, интерфейсов и делегатов. Чтобы начать исследование таких типов, рассмотрим роль перечисления (enum), создал новый проект консольного приложения.

  • На заметку! Не путайте термины перечисление и перечислитель; они обозначают совершенно разные концепции. Перечисление - специальный тип данных, состоящих их пар "имя-значение". Перечислитель - тип класса или структуры, который реализует интерфейс .NET по имени IEnumerable. Обычно упомянутый интерфейс реализуется классами коллекций, а также классом System.Array.

При построении какой-либо системы часто удобно создавать набор символических имен, которые отображаются на известные числовые значения. Например, в случае создания системы начисления заработной платы может возникнуть необходимость в ссылке на типы сотрудников с применением констант вроде вице-президент, менеджер, подрядчик, рядовой сотрудник. Для этой цели в C Sharp поддерживается понятие специальных перечислений. Например, далее представлено специальное перечисление по имени EmpType (его можно определить в том же файле, где находится класс Program, прямо перед определением класса):

// Специальное перечисление.
enum EmpType
{
Manager, // = 0
Grunt, // = 1
Contractor, // =2
VicePresident // =3
}

В перечислении EmpType определены четыре именованные константы, которые соответствуют дискретным числовым значениям. По умолчанию первому элементу присваивается значение 0, а остальным элементам значение устанавливаются по схеме n+1. При желании исходное значение можно изменять походящим образом. Например, если имеет смысл нумеровать члены EmpType со значения 99 до 102, тогда можно поступить следующим образом:

// Начать нумерацию со значения 99.
enum EmpType
{
Manager = 99,
Grunt, // = 100
Contractor, // = 101
VicePresident // = 102
}

Нумерация в перечислениях не обязательно должна быть последовательной и содержать только уникальные значения. Если (по той или иной причине) перечисление EmpType необходимо сконфигурировать так, как показано ниже, то компиляция пройдет гладко и без ошибок:

// Значения элементов в перечислении не обязательно должны быть
// последовательными!
enum EmpType
{
Manager = 10,
Grunt = 1,
Contractor = 100,
VicePresident = 9
}

Объявление переменных типа перечисления

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

class Program
{
static void Main(string[] Main)
{
Console.WriteLine("Забавы с enum");
// Создать переменную типа EmpType.
EmpType emp = EmpType.Contractor;
AskForBonus(emp);
Console.ReadLine();
}

// Перечисления как параметры.
static void AskForBonus(EmpType e)
{
switch (e)
{
case EmpType.Manager:
Console.WriteLine("Не желаете ли взамен фондовые опционы?");
break;

case EmpType.Grunt:
Console.WriteLine("Вы должно быть шутите");
break;

case EmpType.Contractor:
Console.WriteLine("Вы уже получаете вполне достаточно");
break;

case EmpType.VicePresident:
Console.WriteLine("Очень хорошо, сэр!");
break;
}
}
}

Обратите внимание, что когда переменной enum присваивается значение, вы должны указывать перед этим значением (Grunt) имя самого перечисления (EmpType). Из-за того, что перечисления представляют собой фиксированные наборы пар "имя-значение", установка переменной enum в значение, которое не определено прямо в перечислимом типе, не допускается:

static void ThsMethodWillNotCompile()
{
// Ошибка! SalesManager отсутствует в перечислении EmpType!
EmpType emp = EmpType.SalesManager;

// Ошибка! Не указано имя EmpType перед значением Grunt!
emp = Grunt;
}

Тип System.Enum

С перечислениями .NET связан один интересный аспект - они получают свою функциональность от класса System.Enum. В классе System.Enum определено множество методов, которые позволяют исследовать и трансформировать заданное перечисление. Одним из них является метод Enum.GetUnderlyingType(), который возвращает тип данных, используемый для хранения значений перечислимого типа(System.Int32 в текущем объявлении EmpType):

static void Main(string[] args)
{
Console.WriteLine("Забавы с enum");
// Создать переменную типа EmpType.
EmpType emp = EmpType.Contractor;
AskForBonus(emp);
// Вывести тип хранилища для значений перечисления.
Console.WriteLine("EmpType использует {0} для хранения",
Enum.GetUnderlyingType(emp.GetType()));
Console.ReadLine();
}

Заглянув в браузер объектов Visual Studio, можно удостовериться, что метод Enum.GetUnderlyingType() требует передачи System.Type в качестве первого параметра.

Один из возможных способов получения метаданных (как демонстрировалось ранее) предусматривает применение метода GetType(), который является общим для всех типов в библиотеках базовых классов .NET. Другой подход заключается в использовании операции typeof языка C Sharp. Преимущества такого способа связано с тем, что он не требуется объявления переменной сущности, описание метаданных которой требуется получить:

// На этот раз для получения информации о типе используется операция typeof.
Console.WriteLine(EmpType использует {0} для хранения", Enum.GetUnderlyingType(typeof(EmpType)));

Конец

Спасибо, если вы прочитали эту статью. Надеюсь вы что-то новое узнали для себя, и конечно же поняли. Подпишитесь, поставьте лайк, напишите комментарий, поддержите меня. Хотелось бы увидеть как улучшать статьи и чего не хватает. Буду анализировать и улучшать контент. Еще раз спасибо, до свидания! :)