Нэш Трей - C# 2010. Ускоренный курс для профессионалов (2010) (1160865), страница 66
Текст из файла (страница 66)
По умолчанию регулярные выражения интерпретируются во время выполнения. Сложные регулярные выражения могут потреблять значительное время работы процессора, когда механизм регулярных выражений станет их обрабатывать. Для таких ситуаций рассмотрите возможность применения опции Сошрг1ес1. Эта опция заставит представить регулярное выражение кодом 1Ь, сгенерированным ЛТ-компилятором. Это замедлит первое применение регулярного выражения, но при частом использовании окупится с лихвой. К тому же не забудьте, что ЛТ-компилированный код увеличивает рабочий набор приложения. Часто возникает потребность в поиске,не зависящем от регистра.
Это можно указать в шаблоне регулярного выражения, но тогда его читабельность ухудшится. Намного проще передать флаг 1опогеСзяе при создании экземпляра Кедех. Используя этот флаг, механизм Редел также примет во внимание специфичные для культуры проблемы нечувствительности к регистру, обратившись к экземпляру Сп1Тпге1пго, ассоциированному с текущим потоком. Если необходимо выполнять независимый от регистра поиск независимым от культуры способом, комбинируйте флаг 1спогеСзяе с флагом Сп1тпге1пгзг1зпТ. Флаг 1 с по ге Рзс Те гпкпг Те я рясе также полезен для сложных регулярных выражений.
Этот флаг сообщает механизму регулярных выражений о необходимости игнорировать все пробелы внутри выражения соответствия, а также игнорировать все комментарии в строках, следующие за символом а. Это позволяет удобно комментировать действительно сложные регулярные выражения. Например, ниже показано, как модифицировать предыдущий пример поиска 1Р-адреса, используя 1дпогераТТегпМЬЬТеярзсе: пя1пс Яуягеш; пя1пс Яузгеш.техг.аедп1згахргеязгопя; рпЬ11с с1азя Епзгуро1пТ ( зззггс готе Мзгп( я гтпд() згдз ) 11( эгоз.ЬепсТП < 1 ) Сопзо1е.мг1ТеЬгпе( "Вы должны предоставить строку." гезпгп; // Создать регулярное зырзжение для поиска шаблона 1Р-здресз. зсгапд раТТегп = 6" 248 Глава 8 4 Первая часть совпадения ([01)?10Ы? 4 По крайней мере, одна цифра, возможно, 4 предваренная 0 или 1, за которой, 4 возможно, следует другая цифра 4 или (2[0-4) 10 Ф Начинается с 2, затем идет число 0-4 4 и затем любая цифра 4 ИЛИ (25[0-5]) 4 25, за 4 Целая группа, 4 ПОВТОР ([01]?1%0?(2(0-4) 4 ПОВТОР <(01)?1 Г,б?(2[0-4] 4 ПОВТОР ([01]?1сР~б?(2[0-4) которым следует число 0-5 за которой следует точка.
10(25[0-5]) 1. 1б(25[0-5])1. 10(25[0-5)) Весен терех = пен Кесех( раггегп, Кеоехбрс1опз.1дпогераггегпип1гезрасе ) магсь юассп = гесех.магов( агчз[0) ); на11е( загон.зцссезз ) ( Сопзо1е.нг11е01пе( "1Р-адрес найден в позиции (О) со " 4 "значением (1)", загс)1. 1пбех, юапсПЛа1ие юассн = юагсп.нехгиагсп(); Обратите внимание, насколько выразительными могут быть комментарии внутри регулярного выражения. С учетом высокой сложности некоторых регулярных выражений, они никогда не будут лишними. Резюме В этой главе была затронута лишь верхушка айсберга возможностей обработки строк. имеющихся в .ХЕТ Ргзшеч<огК и СВ. Из-за широкого распространения строкового типа проектировщики С[.Х вместо того, чтобы просто включить его в базовую библиотеку классов, отнесли его к набору встроенных типов.
Это мудрое решение, учитывая, часто применяются строки. Более того, в библиотеке предусмотрена исчерпывающая реализация специфичных для культуры шаблонов через Сц1тцге1пТо. что обычно требуется при создании глобальных приложений, интенсивно работающих со строками. В главе было показано, как создавать собственные культуры с использованием класса Сц11цгеАпбкец1оп1пговц11с(ег. По сути, любое программное обеспечение, напрямую взаимодействующее с пользователем и предназначенное для глобального применения, должно быть готовым обслуживать специфичные локальные потребности.
И, наконец, был проведен краткий экскурс в мир возможностей . ХЕТ Егатпеног)с по обработке регулярных выражений, хотя изложение полного руководства по языку регулярных выражений и не входило в список намерений. Как можно было убедиться, средства обработки строк и текстов, встроенные в С1Л, .ХЕТ ггагпечюг)с и язык СВ, отлично продуманы и удобны в применении. В следующей главе рассматриваются массивы и другие развитые типы коллекций, доступные в ХЕТ Ртагпе<чогК.
Кроме того, будет описана новая подцержка итераторов в СВ. ГЛАВА Массивы, типы коллекций и итераторы т ипы коллекций окружают нас, начиная с самых истоков программирования. Наверняка вы помните упражнения со связными списками, которые приходилось выполнять всем, кто учился программированию. В этой главе будет представлен краткий обзор массивов, не слишком погружаясь в детали, поскольку массивы не особенно меняются между выпусками . НЕТ. Однако больше внимания будет уделено объяснению основных обобщенных интерфейсов коллекций и итераторов, вместе с описанием тех замечательных вещей, которые можно с ними делать.
Создание перечислителей для типов коллекций традиционно было утомительным и скучным делом. Итераторы облегчили эту задачу, при этом значительно повысив читабельность кода. Представление массивов Массивы С№, как и массивы С1В, в значительной мере происходят от массивов С/С++. В С/С++ для обращения к массивам применяется указатель, который вначале указывает на начало непрерывного диапазона элементов, находящихся в некотором блоке памяти. Массивы С/С++ не имеют встроенных средств контроля диапазона, что является причиной многих ошибок, с которыми вам наверняка приходилось сталкиваться.
В С№ и С1Я зта проблема элегантно решена за счет превращения массивов во встроенный, неявный тип исполняющей системы. При объявлении типа — будь то класс или структура — исполняющая система оставляет за собой право молча сгенерировать тип массива, основанный на этом новом типе. Сгенерированный тип массива является ссылочным типом, т.е. экземпляры массива — это классы. Этот сгенерированный тип наследуется ог Яузсев.
Аггау и, в конце концов — от Яузсет. Сээ1есс. Таким образом, все массивы С№ можно трактовать полиморфно — через ссылку на Яузсеж. Аггау. Конечно, это означает, что каждый массив, независимо от конкретного типа его элементов, реализует все методы и свойства Яузсев.Аггау. Способ объявления массивов в С№ похож на С/С++, за исключением того, что проектировщики языка постарались сделать синтаксис несколько более интуитивно понятным на их взгляд — квадратные скобки в объявлении следуют за типом, а не за именем переменной. 260 Глава 9 В следующем примере продемонстрированы три способа создания массива; пзгпд гузеево рсЬ1гс с1азз Епсгуэо1пс [ згаггс нозс мазо[) [ Тпс[) аггау1 = пен Тпс[ 10 ); гог[ Тпс 1 = 0; 1 < аггау1.1епдс)п ++1 ) [ аггау1[1) = 1*2г ) гпг[) аггау2 = пен глг[] [ 2, 4, 6, 8 гас[) аггауЗ = [ 1, 3, 5, 7 )г Обычный способ создания экземпляра массива и наполнения его начальными значениями показан на примере инициализации массива аггау1.
Элементы индексируются с применением индексатора, который обычно больше или равен О. Возможно, вам уже известно, что массивы в СЬК могут иметь нижнюю границу, определяемую пользователем. Однако в СВ нижняя граница массива всегда равна О, чтобы соответствовать ограничению СЬН, гласящему, что массивы должны иметь нулевую нижнюю границу. Приемы инициализации, использованные в отношении массивов аггау2 и аггауЗ, показывают сокращенную нотацию решения той же задачи.
Обратите внимание. что во всех случаях необходимо сначала разместить экземпляры массива в куче с помощью операции пен. То же происходит и с экземпляром аггауЗ, но здесь компилятор делает это за вас, позволяя сократить нотацию. Интересно отметить, что массив типа оЬ.'ест — те. Буэсем.ОЬ]ест [] — сам имеет тип Яуэсев.ОЬЗесс.
Одно из удобств массивов .)чЕТ связано с тем, что они обеспечивают контроль диапазона. Поэтому при попытке выхода за границу массива возникнет ошибка времени выпалнення — исполняющая система сгенерирует исключение 1поехОпГОГЕапдеЕхсерсуоп вместо обращения к случайному участкупамяти, как это происходит в С/Сч к Так что можно попрощаться с этими коварными, трудно обнаруживаемыми ошибками, поскольку СЕЯ не позволит им прятаться очень долго, потому они определенно не останутся незамеченными в течение длительного времени. И, наконец, обратите внимание на возможность осуществления удобной итерации по элементам массива с помощью оператора Тогеасп.
Причина в том, что Буэсев. Аггау реализует интерфейс 1ЕппвегаЬ1е. Дополнительные сведения о 1ЕппвегаЬ1е и родственном ему интерфейсе 1Епстегасог приведены в разделе "1ЕппмегаЬ1е<Т>, 1Епппегасог<Т>, 1ЕпсмегаЬ1е и 1Еппгяегасог" далее в главе.
На заметку! Во время компиляции цикла Тогеасс е действительности проводится некоторая оптимизация, кзк будет указано е главе 13, Вместо преобразования массива е экземпляр 1епстегаь1е и последующего вызова 1епцтегаь1е. Оесепптегагог, просто производится вызов любого общедоступного метода аегепптегэсог, который соответствует требуемой сигнатуре.
Эта оптимизация представляет собой форму утиной типизации, о которой более подробно речь пойдет в главе 17. Несмотря на то что цикл Тогеасс использует эту оптимизацию, есе равно имеет смысл реализовать интерфейсы 1епптегаь1е и 1епстегаь1е<т>, поскольку потребителю может понадобиться выполнять итерацию по коллекции не только в цикле Гогеаси, а, скажем, через [ЗМО. Массивы, типы коллекций и итераторы 26! Неявно типизированные массивы В СЕ 3.0 появился сокращенный способ инициализации массивов, когда конкретный тип массива может быть выведен во время выполнения. Взглянем на новый синтаксис на примере следующего фрагмента кода: паапа зуясеа) рцЬ11с с1аяя Епкгууоапс ( ясясас уогб Маап() ( // Традиционный массив 1пг[] сопуепсаопа1Аггяу = пен Тпс[] ( 1, 2, 3 )т // Неявно типизированный массив уяг Тар11сак1утурес)Аггау = пен (] ( 4, 5, б )т Сопяо1е.нг1се11пе( 1ир11с1Г1утурес(Аггяу.бестуре О )т // Массив т(оцЬ1е няг яотпеыциЬегя = пен [] ( 3.1415, 1, б )т Сопяо1е.игасе11пе( яоаеышппегя.пестуре() )~ // Не скомпилируется! // уяг яоаеасгапчз = пен [] ( "1пк", // яоаеышппегя.пестуре() )т ) ) Здесь для первой переменной массива по имени сопуепгаопа1Аггау используется один из вариантов традиционного синтаксиса объявления и инициализации массива.














