Полное руководство. С# 4.0 - Шилдт Герберт
Шрифт:
Интервал:
Закладка:
Для каждой последующей символически обозначаемой константы в перечислениизадается целое значение, которое на единицу больше, чем у предыдущей константы.По умолчанию значение первой символически обозначаемой константы в перечислении равно нулю. Следовательно, в приведенном выше примере перечисления Appleконстанта Jonathan равна нулю, константа GoldenDel — 1, константа RedDel — 2и т.д.
Доступ к членам перечисления осуществляется по имени их типа, после которогоследует оператор-точка. Например, при выполнении фрагмента кодаConsole.WriteLine(Apple.RedDel + " имеет значение " + (int)Apple.RedDel);
выводится следующий результат.RedDel имеет значение 2
Как показывает результат выполнения приведенного выше фрагмента кода, для вывода перечислимого значения используется его имя. Но для получения этого значениятребуется предварительно привести его к типу int.
Ниже приведен пример программы, демонстрирующий применение перечисления Apple.// Продемонстрировать применение перечисления.using System;class EnumDemo { enum Apple { Jonathan, GoldenDel, RedDel, Winesap, Cortland, McIntosh }; static void Main() { string[] color = { "красный", "желтый", "красный", "красный", "красный", "красновато-зеленый" }; Apple i; // объявить переменную перечислимого типа // Использовать переменную i для циклического // обращения к членам перечисления. for(i = Apple.Jonathan; i <= Apple.McIntosh; i++) Console.WriteLine(i + " имеет значение " + (int)i); Console.WriteLine(); // Использовать перечисление для индексирования массива. for(i = Apple.Jonathan; i <= Apple.McIntosh; i++) Console.WriteLine("Цвет сорта " + i + " — " + color[(int)i]); }}
Ниже приведен результат выполнения этой программы.Jonathan имеет значение 0GoldenDel имеет значение 1RedDel имеет значение 2Winsap имеет значение 3Cortland имеет значение 4McIntosh имеет значение 5Цвет сорта Jonathan - красныйЦвет сорта GoldenDel - желтыйЦвет сорта RedDel - красныйЦвет сорта Winsap - красныйЦвет сорта Cortland - красныйЦвет сорта McIntosh - красновато-зеленый
Обратите внимание на то, как переменная типа Apple управляет циклами for.Значения символически обозначаемых констант в перечислении Apple начинаются снуля, поэтому их можно использовать для индексирования массива, чтобы получитьцвет каждого сорта яблок. Обратите также внимание на необходимость производитьприведение типов, когда перечислимое значение используется для индексированиямассива. Как упоминалось выше, в C# не предусмотрены неявные преобразованияперечислимых типов в целочисленные и обратно, поэтому для этой цели требуетсяявное приведение типов.
И еще одно замечание: все перечисления неявно наследуют от класса System.Enum,который наследует от класса System.ValueType, а тот, в свою очередь, — от классаobject.Инициализация перечисления
Значение одной или нескольких символически обозначаемых констант в перечислении можно задать с помощью инициализатора. Для этого достаточно указать послесимволического обозначения отдельной константы знак равенства и целое значение.Каждой последующей константе присваивается значение, которое на единицу большезначения предыдущей инициализированной константы. Например, в приведенномниже фрагменте кода константе RedDel присваивается значение 10.enum Apple { Jonathan, GoldenDel, RedDel = 10, Winesap, Cortland, McIntosh };
В итоге все константы в перечислении принимают приведенные ниже значения.Jonathan0GoldenDel1RedDel10Winesap11Cortland12McIntosh13Указание базового типа перечисления
По умолчанию в качестве базового для перечислений выбирается тип int, тем неменее перечисление может быть создано любого целочисленного типа, за исключением char. Для того чтобы указать другой тип, кроме int, достаточно поместить этоттип после имени перечисления, отделив его двоеточием. В качестве примера ниже задается тип byte для перечисления Apple.enum Apple : byte { Jonathan, GoldenDel, RedDel, Winesap, Cortland, McIntosh };
Теперь константа Apple.Winesap, например, имеет количественное значение типаbyte.Применение перечислений
На первый взгляд перечисления могут показаться любопытным, но не очень нужным элементом С#, но на самом деле это не так. Перечисления очень полезны, когдав программе требуется одна или несколько специальных символически обозначаемыхконстант. Допустим, что требуется написать программу для управления лентой конвейера на фабрике. Для этой цели можно создать метод Conveyor(), принимающий вкачестве параметров следующие команды: "старт", "стоп", "вперед" и "назад". Вместотого чтобы передавать методу Conveyor() целые значения, например, 1 — в качествекоманды "старт", 2 — в качестве команды "стоп" и так далее, что чревато ошибками,можно создать перечисление, чтобы присвоить этим значениям содержательные символические обозначения. Ниже приведен пример применения такого подхода.// Сымитировать управление лентой конвейера.using System;class ConveyorControl { // Перечислить команды конвейера. public enum Action { Start, Stop, Forward, Reverse }; public void Conveyor(Action com) { switch(com) { case Action.Start: Console.WriteLine("Запустить конвейер."); break; case Action.Stop: Console.WriteLine("Остановить конвейер."); break; case Action.Forward: Console.WriteLine("Переместить конвейер вперед."); break; case Action.Reverse: Console.WriteLine("Переместить конвейер назад."); break; } }}class ConveyorDemo { static void Main() { ConveyorControl с = new ConveyorControl(); с.Conveyor(ConveyorControl.Action.Start); с.Conveyor(ConveyorControl.Action.Forward); с.Conveyor(ConveyorControl.Action.Reverse); с.Conveyor(ConveyorControl.Action.Stop); }}
Вот к какому результату приводит выполнение этого кода.Запустить конвейер.Переместить конвейер вперед.Переместить конвейер назад.Остановить конвейер.
Метод Conveyor() принимает аргумент типа Action, и поэтому ему могут бытьпереданы только значения, определяемые в перечислении Action. Например, нижеприведена попытка передать методу Conveyor() значение 22.с.Conveyor(22); // Ошибка!
Эта строка кода не будет скомпилирована, поскольку отсутствует предварительно заданное преобразование типа int в перечислимый тип Action. Именно это ипрепятствует передаче неправильных команд методу Conveyor(). Конечно, такоепреобразование можно организовать принудительно с помощью приведения типов,но это было бы преднамеренным, а не случайным или неумышленным действием.Кроме того, вероятность неумышленной передачи пользователем неправильных команд методу Conveyor() сводится с минимуму благодаря тому, что эти команды обозначены символическими именами в перечислении.
В приведенном выше примере обращает на себя внимание еще одно интересноеобстоятельство: перечислимый тип используется для управления оператором switch.Как упоминалось выше, перечисления относятся к целочисленным типам данных,и поэтому их вполне допустимо использовать в операторе switch.
ГЛАВА 13. Обработка исключительных ситуаций
Исключительная ситуация, или просто исключение,происходит во время выполнения. Используя подсистему обработки исключительных ситуаций в С#,можно обрабатывать структурированным и контролируемым образом ошибки, возникающие при выполнениипрограммы. Главное преимущество обработки исключительных ситуаций заключается в том, что она позволяет автоматизировать получение большей части кода, которыйраньше приходилось вводить в любую крупную программу вручную для обработки ошибок. Так, если программанаписана на языке программирования без обработки исключительных ситуаций, то при неудачном выполненииметодов приходится возвращать коды ошибок, которые необходимо проверять вручную при каждом вызове метода.Это не только трудоемкий, но и чреватый ошибками процесс. Обработка исключительных ситуаций рационализирует весь процесс обработки ошибок, позволяя определитьв программе блок кода, называемый обработчиком исключений и выполняющийся автоматически, когда возникаетошибка. Эго избавляет от необходимости проверять вручную, насколько удачно или неудачно завершилась конкретная операция либо вызов метода. Если возникнет ошибка,она будет обработана соответствующим образом обработчиком ошибок.