1629295407-c61bfe4caba98380ea3e7cdae6295416 (846200), страница 63
Текст из файла (страница 63)
ВC++ тип struct — эти тип класса, причем типы struct и class практическиэквивалентны (различие между ними выражается в доступе к их членам по умолчанию: длякласса он принят закрытым, а для структуры — открытым). В C# ключевое слово structиспользуется для определения типов значений, a class — ссылочных типов.ПеречисленияПеречисление (enumeration) — это множество именованных целочисленных констант.Ключевое слово enum объявляет перечислимый тип. Формат записи перечисления таков:enum имя {список_перечисления};Здесь с помощью элемента имя указывается имя типа перечисления. Элементсписок_перечисления представляет собой список идентификаторов, разделенныхзапятыми.Рассмотрим пример.
В следующем фрагменте кода определяется перечислениеapple, которое содержит список названий различных сортов яблок.enum apple { Jonathan, GoldenDel, RedDel, Winsap,Cortland, McIntosh };Здесь важно понимать, что каждый символ списка перечисления означает целоечисло, причем каждое следующее число (представленное идентификатором) на единицубольше предыдущего. Поскольку значение первого символа перечисления равно нулю,следовательно, идентификатор Jonathan имеет значение 0, GoldenDel — значение 1 ит.д.Константу перечисления можно использовать везде, где допустимо целочисленноезначение. Однако между типом enum и встроенным целочисленным типом неявныепреобразования не определены, поэтому при необходимости должна использоваться явнозаданная операция приведения типов.
В случае преобразования одного типа перечисления вдругой также необходимо использовать приведение типов.К членам перечисления доступ осуществляется посредством имени типа и оператора“точка”. Например, при выполнении инструкцииConsole.WriteLine(apple.RedDel + " имеет значение " +(int)apple.RedDel);будет отображено следующее.RedDel имеет значение 2Как подтверждает результат выполнения этой инструкции, при отображениизначения перечислимого типа используется его имя. А для получения его целочисленногозначения необходимо использовать операцию приведения к типу int.
(В этом заключаетсяотличие от ранних версий C#, в которых по умолчанию отображалось целочисленноепредставление значения перечислимого типа, а не его имя.)Теперь рассмотрим программу, которая демонстрирует использование перечисленияapple.// Демонстрация использования перечисления.using System;class EnumDemo {Глава 12. Интерфейсы, структуры и перечисления345enum apple { Jonathan, GoldenDel, RedDel, Winsap,Cortland, McIntosh };public 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 - красно-зеленыйОбратите внимание на то, как for-циклы управляются переменной типа apple.Поскольку перечисление — это целочисленный тип, значение перечисления может бытьиспользовано везде, где допустимы целые значения.
Поскольку значения перечислимоготипа начинаются с нуля, их можно использовать для индексирования массива color(чтобы получить цвет яблок). Заметьте: в этом случае необходимо выполнить приведениетипа. Как упоминалось выше, неявные преобразования между целочисленными иперечислимыми типами не определены. Поэтому без явно заданного приведения типа здесьне обойтись.И еще. Поскольку перечислимые типы представляют собой целочисленные значения,их можно использовать для управления switch-инструкцией (соответствующий примерприведен ниже).346Часть I.
Язык C#Инициализация перечисленийОдно или несколько символов в перечислении можно определить с помощьюинициализатора. Это реализуется путем использования знака “равно” и последующегоцелого значения. Символам, стоящим после инициализатора, присваиваются значения,превышающие предыдущее значение инициализации. Например, следующий фрагмент кодаприсваивает число 10 символу RedDel.enum apple { Jonathan, GoldenDel, RedDel = 10, Winsap,Cortland, McIntosh };Вот какие значения имеют теперь эти символы:Jonathan0GoldenDellRedDel10Winsap11Cortland12McIntosh13Задание базового типа перечисленияПо умолчанию перечисления используют тип int, но можно также создатьперечисление любого другого целочисленного типа, за исключением типа char. Чтобызадать тип, отличный от int, укажите этот базовый тип после имени перечисления идвоеточия.
Например, следующая инструкция создает перечисление apple с базовымтипом byte.enura apple : byte { Jonathan, GoldenDel, RedDel, Winsap,Cortland, McIntosh };Теперь член apple.Winsap, например, представляет собой byte-значение.Использование перечисленийНа первый взгляд может показаться, что перечисления, хотя и представляютопределенный интерес, но вряд ли заслуживают большого внимания C#-программиста.
Этоне так. Перечисления незаменимы, когда в программе необходимо использовать один илинесколько специализированных символов. Например, представьте, что вы пишетепрограмму для управления лентой конвейера на фабрике. Вы могли бы создать методconveyor(), который в качестве параметров принимает следующие параметры: старт,стоп, вперед и назад. Вместо того чтобы передавать методу conveyor() числа (1 длякоманды “старт”, 2 для команды “стоп” и т.д.), что чревато ошибками, вы можете создатьперечисление, которое этим числам присваивает слова. Вот пример такого решения:// Управление лентой конвейера.using System;class ConveyorControl {// Перечисляем команды, управляющие конвейером.public enum action { старт, стоп, вперед, назад };public void conveyor(action com) {switch(com) {case action.старт:Console.WriteLine("Запуск конвейера.");Глава 12. Интерфейсы, структуры и перечисления347}}}break;case action.стоп:Console.WriteLine("Останов конвейера.");break;case action.вперед:Console.WriteLine("Перемещение вперед.");break;case action.назад:Console.WriteLine("Перемещение назад.");break;class ConveyorDemo {public static void Main() {ConveyorControl c = new ConveyorControl();c.conveyor(ConveyorControl.action.старт);c.conveyor(ConveyorControl.action.вперед);c.conveyor(ConveyorControl.action.назад);c.conveyor(ConveyorControl.action.стоп);}}Вот какие результаты генерирует эта программа:Запуск конвейера.Перемещение вперед.Перемещение назад.Останов конвейера.Поскольку метод conveyor() принимает аргумент типа action, этому методумогут передаваться только значения, имеющие тип action.
Вот, например, попыткапередать методу conveyor() значение 22.c.conveyor(22); // Ошибка!Эта инструкция не скомпилируется, поскольку встроенного преобразования из типаint в тип action не существует. Это — своего рода защита от передачи методуconveyor() некорректных команд. Конечно, чтобы “настоять” на таком преобразовании,можно было бы использовать операцию приведения типов, но это потребовало бы заранеепродуманных действий и вряд ли привело к случайной ошибке. Кроме того, посколькукоманды задаются словами, а не числами, маловероятно, что пользователь методаconveyor() по небрежности передаст неверное значение.В этом примере хотелось бы еще обратить ваше внимание вот на что. Типперечисления используется здесь для управления switch-инструкцией.
Как ужеупоминалось, поскольку перечисления считаются целочисленными типами, их можноиспользовать в инструкции switch.348Часть I. Язык C#Полныйсправочник поГлава 13Обработка исключительныхситуацийИсключительная ситуация (или исключение) — это ошибка, которая возникает вовремявыполненияпрограммы.ИспользуяC#-подсистемуобработкиисключительных ситуаций, с такими ошибками можно справляться.
Эта подсистема в C#включает в себя усовершенствованные методы, используемые в языках C++ и Java.Поэтому эта тема будет знакомой для C++- и Java-программистов. Однако обработкаисключений в C# отличается ясностью и полнотой реализации.Преимущество подсистемы обработки исключений состоит в автоматизации созданиябольшей части кода, который ранее необходимо было вводить в программы “вручную”.Например, в любом компьютерном языке при отсутствии такой подсистемы практическикаждый метод возвращал коды ошибок, и эти значения проверялись вручную при каждомвызове метода. Такой подход довольно утомителен, кроме того, при этом возможновозникновение ошибок. Обработка исключений упрощает “работу над ошибками”, позволяяв программах определять блок кола, именуемый обработчиком исключений, который будетавтоматически выполняться при возникновении определенной ошибки.
В этом случае необязательно проверять результат выполнения каждой конкретной операции или методавручную. Если ошибка возникнет, ее должным образом обработает обработчикисключений.Еще одним преимуществом обработки исключительных ситуаций в C# являетсяопределение стандартных исключений для таких распространенных программных ошибок,как деление на нуль или попадание вне диапазона определения индекса. Чтобыотреагировать на возникновение таких ошибок, программа должна отслеживать иобрабатывать эти исключения.Без знания возможностей C#-подсистемы обработки исключений успешноепрограммирование на C# попросту невозможно.Класс System.ExceptionВ C# исключения представляются классами.
Все классы исключений должны бытьвыведены из встроенного класса исключений Exception, который является частьюпространства имен System. Таким образом, все исключения — подклассы классаException.ИзклассаExceptionвыведеныклассыSystemExceptionиApplicationException. Они поддерживают две общие категории исключений,определенные в C#: те, которые генерируются C#-системой динамического управления, илиобщеязыковым средством управления (Common Language Runtime — CLR), и те, которыегенерируются прикладными программами. Но ни класс SystemException, ни классApplicationException не привносят ничего нового в дополнение к членам классаException.