Содержание
Перечисление (enumeration) — это множество именованных целочисленных констант. Перечисляемые типы относятся к значимым типам.
Объявляются перечисляемые типы с помощью ключевого слова enum
. Формат определения такой:
1 | enum имя {список_перечисления); |
Имя задает имя перечисляемого типа, а список перечисления представляет собой список идентификаторов, разделенных запятыми.
Доступ к членам перечисления осуществляется с помощью имени перечисляемого типа и оператора точка.
1 2 3 | public enum BorderSide { Left, Right, Top, Bottom } BorderSide topSide = BorderSide.Top; bool isTop = (topSide == BorderSide.Top); // true |
Каждый член перечисления указывает на целочисленное значение. По умолчанию эти значения имеют тип int
и членам перечисления присваиваются константы 0, 1, 2, … (т.е. целые числа начиная с нуля). Однако для членов перечисления можно задать и другой целочисленный тип:
1 | public enum BorderSide : byte { Left,Right,Top,Bottom } |
Также можно явно задать целочисленные значения для каждого члена:
1 2 | public enum BorderSide : byte { Left=1, Right=2, Top=10, Bottom=11 } |
Можно задать только некоторые члены перечисления, при этом члены, которым не заданы значения, будут увеличиваться на один с последнего заданного члена:
1 2 | public enum BorderSide : byte { Left=1, Right, Top=10, Bottom } |
Значение перечисления можно представить тремя способами:
- как тип
enum
- как лежащее в основе целочисленное значение
- как строку
Значения перечислений могут преобразовываться между этими типами.
Приведение перечислений
Константу перечисления можно использовать везде, где допустимо целочисленное
значение. Однако между типом enum
и встроенным целочисленным типом неявные
преобразования невозможны, поэтому при необходимости должно использоваться
явное приведение типов.
1 2 3 | int i = (int) BorderSide.Left; // Приведение перечисления к значимому типу BorderSide side = (BorderSide) i; // Приведение значения к типу перечисления bool leftOrRight = (int) side <= 2; // Приведение перечисления к значимому типу |
Также можно явно приводить один тип перечисления к другому, при этом преобразование осуществляется через целочисленные значения перечисления.
1 2 3 | HorizontalAlignment h = (HorizontalAlignment) BorderSide.Right; // Эквивалентно: HorizontalAlignment h = (HorizontalAlignment) (int) BorderSide.Right; |
Литерал 0 обрабатывается особо: он не требует явного приведения:
1 2 | BorderSide b = 0; // Не требуется явного приведения if (b == 0) ... |
Экземпляру перечисления можно присвоить значение, которое выходит за пределы значений его членов:
1 2 | BorderSide b = (BorderSide) 12345; Console.WriteLine (b); // 12345 |
Битовые флаги (Flags Enums)
Члены перечислений можно комбинировать (объединять). Чтобы избежать неоднозначности членам комбинируемых перечислений необходимо явно присваивать значения.
1 2 3 | [Flags] public enum BorderSides { None=0, Left=1, Right=2, Top=4, Bottom=8 } |
Комбинировать значения перечислений можно с помощью побитовых операторов, таких как |
и &
.
1 2 3 4 5 6 7 | BorderSides leftRight = BorderSides.Left | BorderSides.Right; if ((leftRight & BorderSides.Left) != 0) Console.WriteLine ("Includes Left"); // Includes Left string formatted = leftRight.ToString(); // "Left, Right" BorderSides s = BorderSides.Left; s |= BorderSides.Right; Console.WriteLine (s == leftRight); // True |
По соглашению комбинированным членам перечисления дается множественное имя, например leftRight
.
Комбинированным перечислениям следует присваивать атрибут Flags
. Если этого не сделать метод ToString
будет возвращать числовые значения, а не последовательность имен. Перечисления с атрибутом flags
называются битовыми флагами.
Сочетания членов можно указывать внутри самих перечисляемых типов:
1 2 3 4 5 6 7 8 9 | [Flags] public enum BorderSides { None=0, Left=1, Right=2, Top=4, Bottom=8, LeftRight = Left | Right, TopBottom = Top | Bottom, All = LeftRight | TopBottom } |
Операторы перечислений
С перечислениями можно использовать следующие операторы:
= == != < > <= >= + - ^ & | ~
+= -= ++ - sizeof
При этом перечисления воспринимаются как целочисленные значения. Сложение возможно только между типом enum
и целочисленным типом, но не между двумя перечислениями.
System.Enum
Класс System.Enum
предоставляет расширенную поддержку типов enum
, обеспечивая унификацию и определяя статические служебные методы. Унификация типов enum подразумевает возможность неявного приведения любого члена перечисления к типу System.Enum
. Статические методы дают возможность выполнения преобразований и получения списка членов.
Статический метод Enum.GetUnderlyingType
возвращает лежащий в основе перечисления целочисленный тип:
1 | Type integralType = Enum.GetUnderlyingType (anyEnum.GetType()); |
Статический метод Enum.ToObject
преобразует целочисленное значение в экземпляр enum
указанного типа:
1 2 | object bs = Enum.ToObject (typeof (BorderSides), 3); Console.WriteLine (bs); // Left, Right |
Преобразовать enum
в строку можно с помощью статического метода Enum.Format
либо с помощью экземплярного метода ToString
. Оба метода принимают форматную строку.
Метод Enum.Parse
преобразует строку в enum
. Он принимает тип enum
и строку, которая может включать множество членов. Необязательный третий аргумент позволяет выполнить разбор не чувствительный к регистру. Если член не найден генерируется исключение ArgumentException
.
1 | BorderSides leftRight = (BorderSides) Enum.Parse (typeof (BorderSides), "Left, Right"); |
Метод Enum.GetValues
возвращает массив, содержащий все члены указанного типа enum:
1 2 | foreach (Enum value in Enum.GetValues (typeof (BorderSides))) Console.WriteLine (value); |
Метод Enum.GetNames
делает тоже самое, но возвращает массив строк.
Форматные строки для перечислений
Для перечислений предусмотрены следующие форматные строки:
- G или g — общий формат применяемый по умолчанию
- F или f — рассматривает экземпляр enum как флаг, позволяя коректно преобразовывать составные члены
- D или d — десятичное значение, извлекает лежащее в основе целочисленное значение и представляет его в виде строки
- X или x — шестнадцатеричное значение, извлекает лежащее в основе целочисленное значение и представляет его в виде шестнадцатеричной записи