1629295403-b876e2087bddebea4bc9666fb2377a02 (846199), страница 81
Текст из файла (страница 81)
Дополнительные глава{if{(nValueOfObject == 0)throw new CustomException("Нельзя делить на 0",this);}return 1.0 /(double)nValueOfObject;public class Program{public static void Main(string[]args)try{// take the inverse of 0MathClass mathObject = new MathClass("Value", 0 ) ;Console.WriteLine("Обратное к d.Value равно { О } " ,mathObj ect.Inverse() ) ;catch(Exception e){}Console.WriteLine("\пНеизвестная фатальная ошибка:\n{0}",e.ToString());// Ожидаем подтверждения пользователяConsole.WriteLine("Нажмите <Enter> для " +"завершения программы..
. ") ;Console.Read();}Класс CustomException несложен. Он хранит сообщение и объект, как это делалкласс MyException ранее. Однако вместо предоставления новых методов для обращения к этим элементам данных он перекрывает существующее свойство Message, которое возвращает сообщение об ошибке, содержащееся в исключении, и методToString ( ) , возвращающий сообщение и трассировку стека.Перекрытие этих функций означает, что даже функции, разработанные для перехватаобобщенного класса Exception, получают ограниченный доступ к новым членамданным. Новый класс лучше обеспечить собственными методами для их данных и оставить нетронутыми методы базового класса.Функция Main () демонстрационной программы начинает с создания объекта MathClass со значением 0, а затем пытается вычислить обратную к нему величину.
Не знаю,как вам, а мне не приходилось видеть разумные результаты деления на 0, так что еслимоя функция вдруг сделает это, я отнесусь к происшедшему с явным недоверием.На самом деле процессоры Intel возвращают значение 1.0/0.0: бесконечность.Имеется ряд специальных значений с плавающей точкой, используемых вместогенерации исключений в языках, которые не поддерживают их. Эти специальные значения включают положительную и отрицательную бесконечности и положительное и отрицательное NaN (Not_a_Number, не число).(пава 18. Эти исключительные исключения415В нормальных условиях метод Inverse () возвращает корректное значение.
Припередаче ему нуля он генерирует исключение CustomException, передавая ему строку пояснения вместе с вызвавшим исключение объектом.Функция Main () перехватывает исключение и выводит короткое сообщение, поясняющее суть происшедшего. "Неизвестная фатальная ошибка", вероятно, означает, тапрограмма "закрывает лавочку и уходит на отдых". Но функция Main () дает исключению шанс пояснить, что же все-таки произошло, вызывая его метод ToString ().Визитка класса: метод T o S t r i n g ()Все классы наследуют один общий базовый класс с именем Object. Об этом уже говорилось в главе 14, "Интерфейсы и структуры".
Здесь, однако, стоит упомянуть о методе ToString () в составе этого класса. Метод предназначен для преобразованиясодержимого класса в строку. Идея заключается в том, что каждый класс должен перекрывать метод ToString ( ) , чтобы осуществить вывод значащей информации.В первых главах был использован метод GetString ( ) , чтобы не касаться в них вопроса наследования; однако принцип остается тем же. Например, корректный методStudent.
ToString () может выводить имя и идентификатор студента.Большинство ф у н к ц и й — даже встроенных в библиотеку С # — применяют методToString () для вывода объектов. Таким образом, перекрытие ToString () имееточень полезное побочное действие, заключающееся в том, что каждый объект выводится в своем собственном формате, безотносительно к тому, кем именно он выведен.Поскольку объект исключения в этом случае на самом деле принадлежит типу CustomException, управление передается CustomException.
ToString ().Метод Message () представляет собой виртуальный метод класса Exception, так что его можно перекрывать, но пользовательское исключение должно наследовать его без перекрытия.Метод Message О позволяет объекту MathClass выводить информацию о самомсебе с использованием метода ToString ( ) . Метод MathClass.ToString() возвращает строку, в которой содержится описание и значение объекта.Не следует брать на себя больше того, что имеете. Используйте метод объектаToString () для создания строковой версии объекта, не пытаясь влезть в самобъект и получить его значения. В общем случае нужно полагаться на открытый интерфейс — открытые члены, — а не на знания о внутреннем устройствеобъекта.
Оно инкапсулировано (по крайней мере должно быть инкапсулировано) и может измениться в новых версиях.Вывод демонстрационной программы CustomException имеет следующий вид:Неизвестная фатальная ошибка:Сообщение <Нельзя делить на 0>, Объект (Value = 0)CustomException.MathClassИсключение сгенерировано в Double Inverse()Нажмите <Enter> для завершения программы...416Часть VII. Дополнительные главаИ последнее: сообщение "Неизвестная фатальная ошибка:" поступает отMain ( ) .
Строка "Сообщение <Нельзя делить на 0>, Объект < ~ ~ > " поступает от CustomException. Часть Value = 0 предоставляет объект MathClass.Последняя строка, Исключение сгенерировано в Double Inverse ( ) , принадлежит CustomException. Это нельзя назвать иначе, как исключительным сотрудничеством.Глава 18. Эти исключительные исключения417Глава 19Работа с файлами и библиотеками> Работа с несколькими исходными файлами в одной программеУ Сборки и пространства имен> Библиотеки классов> Чтение и запись файлов данныхоступ к файлам в С# может иметь два различных значения. Наиболее очевидное — это хранение и считывание данных с диска. О том, как осуществляетсяввод-вывод данных с диска, вы узнаете из этой главы.
Второе значение связанос тем, каким образом исходный текст С# группируется в исходные файлы.Функции позволяют разделить длинную строку исходного текста на отдельные модули, которые можно легче сопровождать и поддерживать. Классы дают возможностьгруппировать данные и функции для дальнейшего снижения сложности программы —программы достаточно сложны, а людям свойственно ошибаться, так что нужно пользоваться любой возможностью упрощения, которая может помочь избежать ошибок.С# обеспечивает еще один уровень группировки: он позволяет сгруппировать подобные классы в отдельную библиотеку.
Помимо написания собственных библиотек, выможете использовать в ваших программах и чужие библиотеки. Такие программы содержат множество модулей, называемых сборками (assemblies). О них также будет рассказано в данной главе. Кроме того, описанное в главе 11, "Классы", управление доступом на самом деле несколько сложнее в связи с применением пространств имен — ещеодного способа группирования похожих классов, которое заодно позволяет избежатьдублирования имен в двух частях программы.
В этой главе речь пойдет и о них.Программы в настоящей книге носят исключительно демонстрационный характер. Каждая из них длиной не более нескольких десятков строк и содержит не более пары классов.Программы же промышленного уровня со всеми "рюшечками" и "финтифлюшечками" могут состоять из сотен тысяч строк кода с сотнями классов.Рассмотрим систему продажи авиабилетов. У вас должен быть один интерфейс длязаказа билетов по телефону, д р у г о й — для тех, кто заказывает билет по Интернету,должна быть часть программы, отвечающая за управление базой данных билетов, дабыне продавать один и тот же билет несколько раз, еще одна часть должна следить за стой-мостью билетов с учетом всех налогов и скидок, и так далее и тому подобное...
Такаяпрограмма будет иметь огромный размер.Размещение всех составляющих программу классов в одном исходном файле Program, с s быстро становится непрактичным. Оно даже более неприемлемо, чем раздеимущества, которого добилась моя бывшая жена, по следующим причинам.У вас возникнут проблемы при поддержке классов. Единый исходный фаочень трудно поддается пониманию. Гораздо проще разбить его на отдельные модули, например ResAgentlnterf асе . cs, GateAgentlnterf асе . cs, Res-jAgent.cs, GateAgent.cs, Fare.cs и Aircraft.cs.Работа над большими программами обычно ведется группами программистов.
Два программиста не в состоянии редактировать одновременно один и таже файл — каждому требуется его собственный исходный файл (или файлы).;У вас может быть 20 или 30 программистов, одновременно работающих над одним большим проектом. Один файл ограничит работу каждого из 24 программистов над проектом всего одним часом в сутки, но стоит разбить программу на 24файла, как становится возможным (хотя и сложным) заставить всех программистов трудиться круглые сутки.
Разбейте программу так, чтобы каждый класс содержался в отдельном файле, и ваша группа заработает как слаженный оркестр.Компиляция больших файлов занимает слишком много времени. В результате босс начнет нервничать и выяснять, почему это вы так долго пьете кофе вместотого, чтобы стучать по клавишам?Какой смысл перестраивать всю программу, когда кто-то из программистов изменил пару строк кода? Visual Studio 2005 может перекомпилировать только измененный файл и собрать программу из уже готовых объектных файлов.По всем этим причинам программисты на С# предпочитают разделять программу наотдельные исходные файлы .
CS, которые компилируются и собираются вместе в единый выполнимый . Е Х Е - ф а й л .Файл проекта содержит инструкции о том, какие файлы входят в проект и какони должны быть скомбинированы друг с другом.Можно объединить файлы проектов для генерации комбинаций программ, которыезависят от одних и тех же пользовательских классов.
Например, вы можете захотеть объединить программу записи с соответствующей программой чтения. Тогда, если изменяется одна из них, вторая перестраивается автоматически. Один проект может описыватьпрограмму записи, второй — программу чтения. Набор файлов проектов известен подназванием решение (solution). (Далее в главе будут рассматриваться две такие программ ы — FileRead и FileWrite, которые можно было бы объединить в одно решение,но это так и не было сделано.)Программисты на Visual С# используют Visual Studio Solution Explorer для объединения нескольких исходных файлов С# в проекты в среде Visual Studio2005.