Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Классы перечисления






Перечисление - это частный случай класса, класс, заданный без собственных методов. Перечисление задает конечное множество возможных значений, которые могут получать объекты класса перечисление. Поскольку у перечислений нет собственных методов, то синтаксис объявления этого класса упрощается, остается обычный заголовок и тело класса, содержащее список возможных значений. Вот формальное определение синтаксиса перечислений:

[атрибуты][модификаторы]enum имя_перечисления[: базовый класс]{список_возможных_значений}

Идентификаторы, заданные в перечислении, как правило, имеют содержательный смысл и являются именами сущностей предметной области. Они используются для организации интерфейса пользователя, при вводе и выводе, при описании действий над объектами перечисления. В памяти компьютера элементы перечисления представлены числами, так что перечисление является числовым типом данных, а не символьным, как могло бы казаться. Множество элементов перечисления проецируется на целочисленный тип данных. По умолчанию элементы перечисления проецируются на начальный отрезок типа int. В этом случае при описании перечисления из n идентификаторов первый из идентификаторов отображается в число 0, последний - в число n-1. Значения, заданные списком, проецируются на плотное подмножество базового класса.

Процессом отображения перечисления на числовой тип данных можно управлять. Базовый класс, который задан при описании перечисления, указывает, в какой тип отображается перечисление. Понятно, что в качестве базового класса можно указывать только классы, задающие целочисленный тип. Кроме типа char, любой целочисленный тип может выступать в роли базового класса. При желании можно задать не только базовый класс, но и интервал представления внутри базового класса. Если для первого идентификатора в списке указать целочисленное значение, то оно будет использоваться как указание задания левой границы интервала представления. Все остальные значения будут проецироваться на интервал с заданной левой границей.

Более того, множество целых, на которое проецируется список элементов перечисления, вовсе не обязано быть плотным. Числовое значение, на которое будет проецироваться данный идентификатор, можно задать для каждого идентификатора. Эта крайне важная и полезная особенность перечислений, активно используемая программистами при работе со шкалами.

 

  • Как упоминалось, перечисления облегчают сопровождение кода, гарантируя, что переменным будут присваиваться только легитимные, ожидаемые значения.
  • Перечисления делают код яснее, позволяя обращаться к целым значениям, называя их осмысленными именами вместо малопонятных " магических" чисел.
  • Перечисления облегчают ввод исходного кода. Когда вы собираетесь присвоить значение экземпляру перечислимого типа, то интегрированная среда Visual Studio с помощью средства IntelliSense отображает всплывающий список с допустимыми значениями, что позволяет сэкономить несколько нажатий клавиш и напомнить о возможном выборе значений.

 

 

Примеры объявлений классов-перечислений:

public enum Profession{teacher, engineer, businessman}; public enum MyColors {red, blue, yellow, black, white}; public enum TwoColors {black, white}; public enum Rainbow {красный, оранжевый, желтый, зеленый, голубой, синий, фиолетовый}; public enum Sex: byte {man=1, woman}; public enum Days: long {Sun, Mon, Tue, Wed, Thu, Fri, Sat};

 

Вот несколько моментов, на которые следует обратить внимание при объявлении перечислений.

  • Как и другие классы, перечисления могут быть объявлены непосредственно в пространстве имен проекта или могут быть вложены в описание класса. Последний вариант часто применяется, когда перечисление используется в интересах одного класса. В этом случае оно может иметь модификатор доступа private.
  • Константы разных перечислений могут совпадать, как в перечислениях MyColors и TwoColors. Имя константы всегда уточняется именем перечисления.
  • Константы могут задаваться словами русского языка, как в перечислении Rainbow.
  • Разрешается задавать базовый класс перечисления. Для перечисления Sex базовым классом является byte, а для перечисления Days - класс long.
  • Разрешается не только задавать базовый класс, но и указывать начальный элемент подмножества, на которое проецируется множество значений перечисления. Для перечисления Sex в качестве базового класса выбран класс byte, а подмножество значений начинается с 1, так что хранимым значением константы man является 1, а woman - 2.
Rainbow color = new Rainbow(); //MyColors color1 = MyColors(MyColors.blue); MyColors color1 = MyColors.white; TwoColors color2; color2 = TwoColors.white; Console.WriteLine(" цвет1 = {0}, цвет2 = {1}", color1, color2); //if(color1! = color2) color2 = color1; if (color1.ToString() == color2.ToString()) Console.WriteLine(COLOR_EQUAL); else Console.WriteLine(COLOR_DIFFERENT); Rainbow color3; color3 = (Rainbow)4;

Пример Печать дня недели.

 

Данный пример иллюстрирует следующие особенности работы с объектами перечислений.

  • Объект перечисления можно создать в объектном стиле с использованием операции new. Но у перечислений есть только единственный конструктор без параметров, инициализирующий объект первым по порядку следования значением перечисления.
  • Объекты можно объявлять с явной инициализацией, как color1, или с отложенной инициализацией, как color2. При объявлении без явной инициализации объект получает значение первой константы перечисления, так что color2 в момент объявления получает значение black.
  • Объекту можно присвоить значение, которое задается константой перечисления, уточненной именем перечисления, как для color1 и color2.
  • Нельзя сравнивать объекты разных перечислений, например, color1 и color2. Это разные классы, для которых не определены операции преобразования типа. Но, заметьте, можно сравнивать строки, возвращаемые методом ToString, например, color1.ToSting() и color2.ToString().
  • Метод ToString, наследованный от класса object, для перечислений переопределен. Если для числового значения объекта существует константа перечисления, отображаемая на числовое значение, то в качестве результата возвращается соответствующий идентификатор как строка. В противном случае, когда такого отображения нет, возвращается как строка само числовое значение.
  • Существуют явные взаимно обратные преобразования констант базового типа и констант перечисления. Цикл, печатающий все значения перечисления Rainbow, демонстрирует преобразование объектов типа int в объекты Rainbow. Заметьте, в объекты Rainbow преобразуются числа, выходящие за интервал, на который проецируются константы перечисления.

Битовые маски (Шкалы)

Предположим, что проектируется некоторый содержательный класс, задающий описание множества объектов, например, класс Car, описывающий автомобили, или класс Employee, представляющий описание служащих некоторой фирмы. Для объектов этого класса зададим набор из n бинарных свойств. Бинарность свойства означает, что свойство может принимать только два значения. Служащий может владеть или не владеть иностранными языками, автомобиль может быть легковым или не быть таковым. В таких ситуациях набор таких свойств удобно представить перечислением, заданным в виде шкалы, а в соответствующий содержательный класс следует включить поле, тип которого задан этим перечислением.

Теперь формальное определение.

Перечисление, содержащее n элементов, будем называть шкалой, если отображение задано для каждого элемента перечисления и элемент с индексом k отображается в число 2k.

Каждый объект перечисления, заданного шкалой, представляется целым числом в диапазоне [0, 2n-1]. Это число следует рассматривать как число в двоичной системе счисления - набор из n битов (разрядов), каждый из которых описывает соответствующее свойство объекта. Единица в разряде указывает, что объект обладает данным свойством; ноль означает отсутствие свойства.

class User { bool CanDelete; bool CanRead; bool CanWrite; bool CanModify; bool CanCreate; } [Flags]enum PermissionTypes: int { None = 0, Read = 1, Write = 2, Modify = 4, Delete = 8 Create = 16, All = Read | Write | Modify | Delete | Create} //and the class from before class User { PermissionTypes Permissions = PermissionTypes.None; }

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.