Нэш Трей - C# 2010. Ускоренный курс для профессионалов (2010) (1160865), страница 59
Текст из файла (страница 59)
Кратко рассматривались отличия между.НЕТ 1.1 и последующими версиями С1Л в отношении обращения с необработанными исключениями. Кроме того, было показано, что .гтЕТ 2.0 и последующие версии справляются с такими исключениями в более согласованной манере. Основная часть главы была посвящена описанию приемов создания "пуленепробиваемого" и безопасного к исключениям кода, который гарантирует стабильность системы в отношении неожиданных исключительных ситуаций. Также были описаны ограниченные области выполнения, которые можно применять для того, чтобы откладывать асинхронные исключения во время прерывания потока.
Создание устойчивого, безопасного и нейтрального к исключениям кода — непростая задача. К сожалению, в подавляющем большинстве программных систем, существующих сегодня, данная проблема полностью игнорируется. Это совершенно удручающая ситуация, учитывая богатство информации на эту тему, которая появилась с тех пор, как обработка исключений была добавлена в язык С++. К сожалению, многих программистов безопасность исключений интересует в последнюю очередь. Они ошибочно предполагают, что могут справиться с любой проблемой исключений во время тестирования, разбрасывая операторы кгу по всему коду.
В действительности безопасность исключений — насущная проблема, которая должна приниматься во внимание еще на этапе проектирования программного обеспечения. Пренебрежение этим приводит к появлению нестандартных систем, которые не приносят пользователям ничего, кроме разочарования и потери рынков в пользу тех компаний, разработчики которых тратят немного больше времени на обеспечение безопасности исключений. По мере того, как компьютеры вторгаются в повседневную жизнь все большего и большего количества людей, возрастает вероятность появления государственных нормативных актов, требующих строгого тестирования систем.
которое призвано доказать, что общество может на них положиться. Не думайте, что вас это не коснется. Вполне можно представить ситуацию, когда такие правила могут быть установлены вообще для всего коммерческого программного обеспечения. Приходилось ли вам слышать истории о том. например, как интегрированная система управления воздушным движением целой страны или континента была остановлена из-за программной ошибки г Разве не возненавидите вы разработчика, который пренебрег безопасностью исключений, что послужило причиной возникновения такой ситузцииу В следующей главе рассматриваются основные аспекты работы со строками в С№ и .1ЧЕТ РгатпетаогК. Вдобавок будет затронута важнейшая тема глобализации.
глава 8 Работа со строками ип Яуэееа. Якг1пд — почетный "гражданин" базовой библиотеки классов .)чЕТ ггшпешог(г. Он представляет собой идеальный пример того, как можно создать неизменяемый ссылочный тип, который ведет себя как тип значения. ОбзоР З~гхпд Экземпляры Якгзпд являются неизменяемыми в том смысле, что, однажды создав их, вы не можете их изменять.
Хотя поначалу это может показаться неэффективным, такой подход на самом деле повышает эффективность кода. Вызов на строке метода 1С1опеаЬ1е. С1опе приводит к получению экземпляра, указывающего на те же строковые данные, что и источник. На самом деле 1С1опеаЬ1е. С1опе просто возвращает ссылку на спуэ. Это совершенно безопасно. потому что общедоступный интерфейс Яег1пя не предоставляет никакой возможности модифицировать действительные данные Яег1пд.
Конечно, можно обмануть систему, применив небезопасный код, но имеет смысл так поступать. Фактически, если нужна строка, представляющая собой глубокую копию исходной строки, то для ее получения можно вызвать метод Сору. Нв заметку! Те, кто знаком с общими шаблонами и идиомами проектирования, могут распознать здесь идиому "Палс)е/бобу" (дескриптор/тело) или "елче)оре/(екег" (конверт/письмо). В С++ зта идиома обычно реализуется при проектировании типов, основанных на ссылках, которые можно передавать по значению. Многие реализации стандартной библиотеки Сч.ч реализуют стандартные строки именно таким образом.
Однако благодаря управляемой сборщиком мусора куче С№, не нужно беспокоиться о поддержке счетчика ссылок на лежащие в основе данные. Во многих средах, в том числе С++ и С. строка не всегда является встроенным типом, а представляет собой более пршиитивнуто. сырую конструкцию, такую как указатель на первый элемент в массиве символов. Обычно процедуры манипуляции со странами не являются частью языка, но частью библиотеки, используемой вместе с языком. Хотя это почти верно и для С№, ситуацию немного затеняет исполняющая система .)ЧЕТ.
Проектировщики спецификации СЫ могли бы представить строки в виде простых массивов типа Я узсегл. сна г, но они предпочли вместо этого включить в коллекцию встроеннык типов Я уз сев. 5 с ге др Фактически Яуэсев. Ясг1пд стоит особняком в коллекции встроенных типов, поскольку является типом ссылочным, а большинство встроенных типов — типы значений. Однако это отличие нивелируется тем фактом, что тип Яегапд ведет себя в соответствие с семантикой значений. Возможно, вы уже знаете, что тип Яуэкегз. Яег1пд представляет строку символов 1)п)соде, а 5 уз Сегл.
Спас — 16-битный символ 1)гцсобе. Конечно, это облегчает локализацию и переносимость на другие операционные системы. Однако иногда может понадо- 224 Глава Я биться интерфейс с внешними системами, в которых используется кодирование строк, отличное от 1)п)соде, Для таких случаев можно применить класс яуягеп. техС . Епсос(1пп, который позволяет преобразовать строки между разными системами кодирования, включая АБС!1, [)ТР-7, ВТР-8 и 1)Тг -32.
Кстати, исполняющая система использует внутри себя для представления 1)и[соде формат [)ТГ-16'. Строковые литералы При использовании строкового литерала в коде С№ компилятор создает объект Яуясек. ЯСггпч, который затем помещается во внутреннюю таблицу модуля, именуемого внутренним пулом. Идея заключается в том, что всякий раз, когда в коде объявляется новый строковый литерал, компилятор сначала проверяет, не объявлен ли он ранее где-нибудь еще, и если это так, то код просто ссылается на уже имеющийся литерал.
Взглянем на пример объявления строкового литерала в С№: пяап0 Яуягеа; рпЬ11с с1авя Епггугогпг ясасао чо10 маго( всггпо[) агчв ) ( ясг1пд 1гс1 =. "с:11нгпоонв11вувсеы32") всггпч 1112 = Н"с:1нспоонв1яуясеп32"; ягг1пд 11СЗ =- №" Засг апп 0111 Непг пр СЬе Ьг11... Сопво1е.кг1гещпе( 11СЗ ); Сопво1е.ягггеь№пе( "ОЬЗесг.аегЕЧ(11С1, 1112): (О)", ОЬЗесг.аесегепсеЕЧпа1я(1гг1, 1>С2) гс( агчя.йепчСЬ > 0 ) ( Сопяо1е.нг1ге11пе( "Полученный параметр: (О)", агчя[0] ясг1пч всгкен = ясг1п0.1псегп( агчя(0) )) Сопво1е.яг1Се11пе( "ОЬЗесг.аеГЕЧ(11С1, вггнен): (О)", ОЬЗесг.аегегепсеЕЧпа1я(11С1, яггнен) Для начала обратите внимание на объявление двух литеральных строк — 11С1 и 1гс2.
Объявленным типом является всгапд, который в С№ представляет собой псевдоним для Яуягеы. ЯСгапд. Первый экземпляр инициализируется обычным строковым литералом, который может содержать знакомые управляющие последовательности, используемые в С и С++, такие как 1с и М. Поэтому сам символ обратного слэша должен быть защищен, как обычно, удвоением. Дополнительную информацию о допустимых управляющих последовательностях можно найти в документации МВР))). Однако С№ предлагает особый тип объявления строки, называемый дословньсми сгпроками [уегЬаШп вСг(пйв), где все, что находится внутри объявления строки, помещается в нее без изменений. Такое объявление предваряется символом №, как показано в примере. Следует обратить особое внимание на тот факт, что несколько странное объявление 11сЗ совершенно корректно.
Переносы строки внутри кода трактуются как части строки, что доказывает вывод этой программы. Дословные строки могут быть удобны в тех случаях, когда создаются строки для отправки формы и нужно специальным образом 1 Подробнее о стандарте 1)п(соде можно почитать на сайте ннн. оп>попе. огд. Работа со строками 225 компоновать их внутри кода. Единственная управляющая последовательность, которая допустима внутри дословных строк — это "", и она применяется для вставки в строку символа двойной кавычки.
Ясно, что 1хт1 и 1112 содержат строки с одним и тем же значением, даже несмотря на то, что они объявлены по-разному. Учитывая сназанное в предыдущем разделе, можно ожидать, что эти два экземпляра будут ссылаться на один и тот же строковый объект. Фактически тан оно и есть, что подтверждает вывод программы, где они проверяются с помощью ОЬ3 ест. Ее ЕегепсеЕЧпа1я. И, наконец, этот пример демонстрирует использование статического метода Етгтпо. 1птегп.
Иногда может понадобиться определить, находится ли объявленная строка во внутреннем пуле. Если да, может оказаться более эффективным сослаться на нее, чем создавать новый экземпляр. Код принимает строку из командной строки и затем создает новый экземпляр с применением метода Етг1пд. 1псегп. Этот метод всегда возвращает допустимую ссылку на строку, и зто будет либо ссылка на экземпляр строки во внутреннем пуле, либо новая копия строки с переданным значением, которая также будет добавлена во внутренний пул. Если в номандной строке передать "с: 1н1пг1оня'тяуятеа32", то код выдаст следующий вывод: дасх апгГ 3111 Непт ир тпе Ьх11. ОЬ3ест.аегЕЧ(11Ь1, 11С2)г тгае Полученный параметр: с:1н1псомятяуятен32 ОЬ3ест.неЕЕЧ(11Ь1, ятгиен): Тгпе Спецификаторы формата и глобализация Часто возникает необходимость в специфичном форматировании данных, которые приложение отображает пользователям.














