Типы перечислений (Руководство по программированию в C#)

Тип перечисления (называемый также перечислением) предоставляет эффективный способ определения набора именованных интегральных констант, который можно назначить переменной. Например, предположим, что нужно определить переменную, значение которое должно представлять день недели. Имеется только семь имеющих смысл значений, которые может принимать переменная. Для определения этих значений можно использовать тип перечисления, который объявлен с использованием ключевого слова enum.

enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
enum Months : byte { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }; 

По умолчанию базовым типом каждого элемента перечисления является int. Можно задать другой целочисленный тип, используя двоеточие, как показано в предыдущем примере. Полный список возможных типов приводится в описании ключевого слова enum (Справочник по C#).

Чтобы проверить основные числовые значения путем приведения в базовый тип, как показано в следующем примере.

Days today = Days.Monday;
int dayNumber =(int)today;
Console.WriteLine("{0} is day number #{1}.", today, dayNumber);

Months thisMonth = Months.Dec;
byte monthNumber = (byte)thisMonth;
Console.WriteLine("{0} is month number #{1}.", thisMonth, monthNumber);

// Output:
// Monday is day number #1.
// Dec is month number #11.

Далее указаны преимущества использования enum вместо числового типа.

  • Для клиентского кода ясно задается, какие значения допустимы для переменной.

  • В Visual Studio в списке IntelliSense перечисляются определенные значения.

Если не указать значения этих элементов в списке перечислителя, значения будут автоматически увеличиваться ан 1. В предыдущем примере Days.Sunday имеет значение 0, Days.Monday имеет значение 1 и т. д. Когда создается новый объект Days, он будет иметь значение по умолчанию Days.Sunday (0), если только ему явно не присвоить значение. При создании перечисления выберите наиболее логичное используемое по умолчанию значение и присвойте ему значение нуль. В результате этого все перечисления, если при их создании им явно не задать значение, будут иметь по умолчанию это значение.

Если переменная meetingDay имеет тип Days, ей можно (без явного приведения) присвоить только одно из значений, определенных в Days. И если день встречи изменяется, можно назначить новое значение из Days переменной meetingDay:

Days meetingDay = Days.Monday;
//...
meetingDay = Days.Friday;

Примечание

Переменной meetingDay можно присвоить любое произвольное целое значение.Например, эта строка кода не генерирует ошибку: meetingDay = (Days) 42.Но этого делать нельзя, поскольку неявно ожидается, что переменная перечисления принимает одно из значений, определяемых перечислением.Присвоение переменной типа перечисления произвольного значения связано с большим риска возникновения ошибок.

Элементам списка перечислителя типа перечисления можно присвоить любые значения, и можно также использовать вычисленные значения:

enum MachineState
{
    PowerOff = 0,
    Running = 5,
    Sleeping = 10,
    Hibernating = Sleeping + 5
}

Типы перечислений как битовые флаги

Тип перечисления можно использовать для определения битовых флагов, благодаря чему экземпляр типа перечисления может хранить любую комбинацию значений, определенных в списке перечислителя. (Конечно, некоторые комбинации могут не иметь смысла или могут быть недопустимы в коде программы).

Перечисление битовых флагов создается применением атрибута FlagsAttribute и определением соответственным образом значений, так чтобы на них могли выполняться битовые операции AND, OR, NOT и XOR. В перечисление битовых флагов включите именованную константу с нулевым значением, что означает "флаги не установлены". Не придавайте флагу нулевое значение, если оно не означает "флаги не установлены".

В следующем примере определена другая версия перечисления Days, имеющая имя Days2. У Days2 имеется атрибут Flags и каждому значению присваивается следующая степень числа 2. Это позволяет создать переменную Days2 со значением Days2.Tuesday и Days2.Thursday.

[Flags]
enum Days2
{
    None = 0x0,
    Sunday = 0x1,
    Monday = 0x2,
    Tuesday = 0x4,
    Wednesday = 0x8,
    Thursday = 0x10,
    Friday = 0x20,
    Saturday = 0x40
}
class MyClass
{
    Days2 meetingDays = Days2.Tuesday | Days2.Thursday;
}

Чтобы установить флаг на перечислении, используйте побитовый оператор OR, как показано в следующем примере.

// Initialize with two flags using bitwise OR.
meetingDays = Days2.Tuesday | Days2.Thursday;

// Set an additional flag using bitwise OR.
meetingDays = meetingDays | Days2.Friday;

Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Tuesday, Thursday, Friday 

// Remove a flag using bitwise XOR.
meetingDays = meetingDays ^ Days2.Tuesday;
Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Thursday, Friday

Чтобы определить, установлен ли конкретный флаг, используйте побитовый оператор AND, как показано в следующем примере.

// Test value of flags using bitwise AND. 
bool test = (meetingDays & Days2.Thursday) == Days2.Thursday;
Console.WriteLine("Thursday {0} a meeting day.", test == true ? "is" : "is not");
// Output: Thursday is a meeting day.

Дополнительные сведения о том, что необходимо учитывать при определении типов перечислений при помощи атрибута FlagsAttribute, см. в разделе Enum.

Использование методов System.Enum для получения и обработки значений перечислений

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

string s = Enum.GetName(typeof(Days), 4);
Console.WriteLine(s);

Console.WriteLine("The values of the Days Enum are:");
foreach (int i in Enum.GetValues(typeof(Days)))
    Console.WriteLine(i);

Console.WriteLine("The names of the Days Enum are:");
foreach (string str in Enum.GetNames(typeof(Days)))
    Console.WriteLine(str);

Дополнительные сведения см. в разделе [AllMembers.T:System.Enum].

Можно также создать для перечисления новый метод, используя метод расширения. Дополнительные сведения см. в разделе Практическое руководство. Создание нового метода для перечисления (Руководство по программированию в C#).

Важная глава книги

Дополнительные сведения о переменных в Начало Visual C#, visual basic 2010

См. также

Ссылки

emum (Справочник по C#)

Enum

Основные понятия

Руководство по программированию на C#