1629295403-b876e2087bddebea4bc9666fb2377a02 (846199), страница 37
Текст из файла (страница 37)
Несмотря на то что можно говорить о модифика-1ции строки, в С# нет операции, модифицирующей реальный объект s t r i n g . Внешнесоздается впечатление, что масса операторов модифицируют объекты s t r i n g , с которыми работают, но это не так — они всегда возвращают модифицированную строку какновый объект s t r i n g .Например, операция " Е г о и м я -" + " R a n d y " не изменяет ни одну из объеди-няемых строк, а генерирует новую строку " Е г о и м я- R a n d y " .
Одним из побочныхэффектов такого поведения является то, что вы не должны беспокоиться, что кто-то изменит строку без вашего ведома.Рассмотрим следующую демонстрационную программу://////usiM o d i f y S t r i n g - методы к л а с с а S t r i n g не модифицируют самобъект(s.ToUpperOне изменяет строку s; вместо этого онв о з в р а щ а е т новую п р е о б р а з о в а н н у ю строку)ngSystem;namespace{classModifyStringProgram{publicstaticvoidMain(string[]args){// Создание объекта StudentS t u d e n t si = new S t u d e n t ( ) ;sl.sName = "Jenny";// С о з д а е м новый о б ъ е к т с темS t u d e n t s2 = new S t u d e n t ( ) ;s2.sName = s i . s N a m e ;////200жеименем"Изменение" имени объекта si не изменяет самобъект,поскольку ToUpperOв о з в р а щ а е т новуюЧасть III. Объектно-основанное программирована// строку, не влияя на оригиналs2.sName = s i . s N a m e .
T o U p p e r ( ) ;Console.WriteLine("si - { o } ,s1.sName,s2.sName);s2 - {l}",// Ожидаем подтверждения пользователяConsole.WriteLine("Нажмите <Enter> для " +"завершения п р о г р а м м ы . . . " ) ;Console.Read();}II S t u d e n t - п р о с т е й ш и й к л а с с ,class S t u d e n tсодержащий строку{public String sName;}}Объекты класса S t u d e n t si и s2 созданы так, что их члены s N a m e указывают на одни и те же строковые данные.
Вызов метода T o U p p e r () преобразует строку s i . s N a m e ,изменяя все ее символы на прописные. Никаких проблем, связанных с тем, что si и s2указывают на один объект, не возникает, поскольку метод T o U p p e r () не изменяетsName, а создает новую строку, записанную прописными буквами.Вот что выводит на экран приведенная выше программа:Sl - Jenny,s2 - J E N N YНажмите < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы . . .Это свойство строк называется неизменностью (или неизменяемостью).Неизменность строк очень важна для строковых констант. Строка наподобие"Этос т р о к а " представляет собой вид строковой константы, как 1 представляет собой константу типа int. Компилятор, таким образом, может заменитьвсе обращения к одинаковым константным строкам обращением к одной константной строке, что снижает размер получающейся программы.
Такое поведение компилятора было бы невозможным, если бы строки могли изменяться.Сравнение строкМножество операций рассматривает строку как единый о б ъ е к т — например, методCompare ( ) , который сравнивает две строки, вводя для них отношение "меньше-больше".Если левая строка больше правой, C o m p a r e () возвращает 1.Если левая строка меньше правой, C o m p a r e () возвращает -1.Если строки равны, C o m p a r e () возвращает 0.Вот как выглядит алгоритм работы C o m p a r e ( ) , записанный с использованием псевдокода:compare (string s l ,s t r i n g s2){Глава ft Работа со строками в С #// Циклический проход по всем символам строк, пока один из// символов одной строки не окажется больше// соответствующего ему символа второй строкиf o r e a c h (для к а ж д о г о ) с и м в о л а б о л е е к о р о т к о й с т р о к иif (числовое з н а ч е н и е с и м в о л а с т р о к и sl > ч и с л о в о г оз н а ч е н и я с и м в о л а с т р о к и s2)return 1if (числовое значение символа строки sl < ч и с л о в о г оз н а ч е н и я с и м в о л а с т р о к и s2)r e t u r n -1// Если все символы совпали, но строка sl длиннее строки// s2, то она считается больше строки s2if В строке sl остались символыreturn 1// Если все символы совпали, но строка s2 длиннее строки//, s l , т о о н а с ч и т а е т с я б о л ь ш е с т р о к и s lif В с т р о к е s2 о с т а л и с ь с и м в о л ыr e t u r n -1// Если все символы строк попарно одинаковы, и строки// и м е ю т одну и ту же д л и н у — то это о д и н а к о в ы е строкиreturn О}Таким образом, " a b e d " больше " a b b d " , a " a b e d e " больше " a b e d " .
Как правило,в реальных ситуациях интересует не то, какая из строк больше, а равны ли две строкидруг другу или нетСравнение строк "больше-меньше" необходимо для их сортировки.Операция C o m p a r e () возвращает значение 0, если две строки идентичны. В приведенной далее тестовой программе это значение используется для выполнения ряда операций, когда программа встречает некоторую строку или строки.Программа B u i l d A S e n t e n c eпредлагает пользователюввести несколькострок текста.
Эти строки объединяются с предыдущими для построениединого предложения. Программа завершает работу, если пользователь вводит слово E X I T , e x i t , Q U I T или q u i t .// BuildASentence - данная программа конструирует// предложение путем конкатенации пользовательского ввода,// до тех пор пока пользователь не введет команду// завершения.
Эта программа демонстрирует использование// проверки равенства строкusing System;namespace BuildASentence{publicclassProgram{publicstatic void Main(string[]args){Console.WriteLine("Каждая введенная вами строка"будет добавляться в предложение, "202ЧастьIII.Объектно-основанное"программирована"пока вы не введете E X I T or Q U I T " ) ;// З а п р а ш и в а е м п о л ь з о в а т е л ь с к и й в в о д и с о е д и н я е м// вводимые п о л ь з о в а т е л е м ф р а з ы в е д и н о е ц е л о е , пока// не будет введена команда з а в е р ш е н и я р а б о т ыstring s S e n t e n c e = "" ;for( ; ; ){// Получение очередной строкиConsole.WriteLine("Введите с т р о к у " ) ;string s L i n e = C o n s o l e .
R e a d L i n e ( ) ;// Выход при команде завершенияif ( I s T e r m i n a t e S t r i n g ( s L i n e ) ){break;}// В п р о т и в н о м с л у ч а е д о б а в л е н и е в в е д е н н о г о к с т р о к еsSentence = S t r i n g . C o n c a t ( s S e n t e n c e , s L i n e ) ;// Обратная связьConsole.WriteLine("\пВы ввели: { о } " , s S e n t e n c e ) ;}Console.WriteLine("\пПолучилось:\n{OJ", s S e n t e n c e ) ;// Ожидаем п о д т в е р ж д е н и я п о л ь з о в а т е л яConsole.WriteLine("Нажмите <Enter> для " +"завершения п р о г р а м м ы . ..'"')•;Console.Read();}// I s T e r m i n a t e S t r i n g - в о з в р а щ а е т t r u e , е с л и в в е д е н н а я/ / строка п р е д с т а в л я е т с о б о й к о м а н д у з а в е р ш е н и я р а б о т ыpublic s t a t i c b o o l I s T e r m i n a t e S t r i n g ( s t r i n g s o u r c e ){string[] s T e r m s = { " E X I T " , " e x i t " , " Q U I T " , " q u i t " };// Сравниваем в в е д е н н у ю с т р о к у с к о м а н д а м и з а в е р ш е н и я// р а б о т ыforeach(stringsTerminsTerms){// Возвращаем true при совпаденииif ( S t r i n g .
C o m p a r e ( s o u r c e , s T e r m )== 0){}}returntrue;return f a l s e ;После краткого описания своих действий программа создает пустую строку для предложения — s S e n t e n c e , после чего входит в "бесконечный" цикл.Конструкции w h i l e (true)и for (; ;)представляют собой бесконечныециклы, выход из которых осуществляется посредством операторов b r e a k(выход из цикла) или r e t u r n (выход из программы). Эти два цикла эквивалентны, и оба встречаются в реальных программах. О циклах подробно рассказывается в главе 5, "Управление потоком выполнения".Глава 9.
Работа со строками в С #203Далее программа предлагает пользователю ввести строку текста, которую затем считывает с помощью метода R e a d L i n e ( ) . После прочтения строки программа проверяяне является ли введенная строка командой завершения работы, пользуясь для этогофункцией I s T e r m i n a t e S t r i n g ( ) . Эта функция возвращает t r u e , если переданнаястрока — одна из команд завершения работы, и f a l s e в противном случае.По соглашению имя функции, проверяющей некоторое свойство и возвращающей значение t r u e или f a l s e , начинается с Is, H a s , C a n или иного подобного слова. Само собой, это соглашение предназначено исключительно длялюдей, для облегчения понимания и удобочитаемости программы — С# безразлично, какое имя используется для функции.Если введенная строка не является командой завершения работы, она добавляетев конец предложения посредством функции S t r i n g .
C o n c a t ( ) . Полученный результатут же выводится на экран, чтобы пользователь мог видеть, что у него получается.Метод I s T e r m i n a t e S t r i n g () определяет массив строк s T e r m s . Каждый членэтого массива представляет собой один из вариантов команды завершения работы. Любая из перечисленных в массиве строк, будучи введенной пользователем, приводит к завершению работы программы.В массив включены как строка " E X I T " , так и строка " e x i t " , поскольку функция C o m p a r e () по умолчанию рассматривает эти строки как различные (так чтодругие варианты написания этого слова, такие как " e x i t " или " E x i t " , не будувосприняты программой в качестве команд завершения).Функция I s T e r m i n a t e S t r i n g () циклически просматривает все элементы массивкоманд завершения работы и сравнивает их с переданной строкой.
Если функция Соmp a r e () сообщает о соответствии строки одному из образцов команд завершения, функция тут же возвращает значение t r u e ; если же до завершения цикла соответствие ненайдено,то по выходе из цикла функция возвращает значениеfa 1 зе.Итерации по массиву — отличный способ проверки на равенство одному извозможных значений.Вот пример вывода программы B u i l d A S e n t e n c e .Каждая введенная вами строка будет добавлятьсяпредложение, пока вы не введете EXIT or QUITВведите строкуПрограммирование на С#Вы ввели: ПрограммированиеВведите строку- сплошное удовольствиенаС#Вы ввели: ПрограммированиеВведите строкуEXITнаС#-всплошное удовольствиеПолучилось:204ЧастьIII.Объектно-основанноепрограммирован*Программирование н а С # - с п л о ш н о е у д о в о л ь с т в и еНажмите < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы .
. .Пользовательский ввод здесь выделен полужирным шрифтом.Сравнение без учета регистраМетод C o m p a r e ( ) , использованный в функции I s T e r m i n a t e S t r i n g ( ) , рассматривает строки " E X I T " и " e x i t " как различные. Однако имеется перегруженная версияфункции C o m p a r e ( ) , которой передается три аргумента. Третий аргумент этой функцииуказывает, следует ли при сравнении игнорировать регистр букв (значение t r u e ) или нет(значение false). О перегрузке функций рассказывалось в главе 7, "Функции функций".Следующая версия функцииI s T e r m i n a t e S t r i n g ()возвращает значение t r u e ,какими бы буквами не была введена команда завершения.// I s T e r m i n a t e S t r i n g - в о з в р а щ а е т з н а ч е н и е t r u e , е с л и// исходная с т р о к а с о о т в е т с т в у е т о д н о й из к о м а н д з а в е р ш е н и я// программыpublic s t a t i c b o o l I s T e r m i n a t e S t r i n g ( s t r i n g s o u r c e ){•// Проверяет, р а в н а ли п е р е д а н н а я с т р о к а с т р о к а м exit/ / или q u i t , н е з а в и с и м о о т р е г и с т р а и с п о л ь з у е м ы х б у к вreturn ( S t r i n g .