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

Обновлен: Июль 2008

Тип перечисления (называемый также перечислением) предоставляет эффективный способ определения набора именованных интегральных констант, который можно назначить переменной. Например, предположим, что нужно определить переменную, значение которое должно представлять день недели. Имеется только семь имеющих смысл значений, которые может принимать переменная. Для определения этих значений можно использовать тип перечисления, который объявлен с использованием ключевого слова 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#).

Далее указаны преимущества использования 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;
Cc138362.alert_note(ru-ru,VS.90).gifПримечание.

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

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

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

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

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

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

В следующем примере определена другая версия перечисления Days, именованное перечисление Days2. Days2 имеет атрибут Flags, и каждое значение, присваиваемое далее, больше степени двух. Это дает возможность создать переменную 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.

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

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

Все перечисления являются экземплярами типа System.Enum. Нельзя произвести новые классы от класса System.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);

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

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

См. также

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

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

Ссылки

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

System.Enum

Журнал изменений

Дата

Журнал изменений

Причина

Июль 2008

Добавлен раздел.

Исправление ошибки содержимого.