программирование. Руководство su P# a n Reference в herbert schildt полное руководство с 0 герберт шилдт
Скачать 3.32 Mb.
|
ГЛАВА 22 Строки и форматирование В этой главе рассматривается класс String, положенный в основу встроенного в C# типа string. Как известно, обработка символьных строк является неотъемлемой частью практически всех программ. Именно по этой причине в классе String определяется обширный ряд методов, свойств и полей, обеспечивающих наиболее полное управление процессом построения символьных строк и манипулирования ими. С обработкой строк тесно связано форматирование данных в удобочитаемой форме. Используя подсистему форматирования, можно отформатировать данные всех имеющихся в C# числовых типов, а также дату, время и перечисления. Строки в с# Вопросы обработки строк уже обсуждались в главе 7, и поэтому не стоит повторяться. Вместо этого целесообразно дать краткий обзор реализации символьных строк в С#, прежде чем переходить к рассмотрению класса String. Во всех языках программирования строка представляет собой последовательность символов, но конкретная ее реализация отличается в разных языках. В некоторых языках программирования, например в C++, строки представляют собой массивы символов, тогда как в C# они являются объектами встроенного типа данных string. Следовательно, string является ссылочным типом. Более того, string – это имя стандартного для среды .NET строкового типа System. String. Это означает, что в C# строке как объекту доступны все методы, свойства, поля и операторы, определенные в классе String. После создания строки последовательность составляющих ее символов не может быть изменена. Благодаря этому ограничению строки реализуются в C# более эффективно. И хотя такое ограничение кажется на первый взгляд серьезным препятствием, на самом деле оно таковым не является. Когда требуется получить строку как разновидность уже существующей строки, достаточно создать новую строку, содержащую требующиеся изменения, и "отвергнуть" исходную строку, если она больше не нужна. А поскольку ненужные строковые объекты автоматически утилизируются средствами "сборки мусора'7, то беспокоиться о дальнейшей судьбе ''отвергнутых 77 строк не приходится. Следует, однако, подчеркнуть, что переменные ссылок на строки могут, безусловно, изменить объект, на который они ссылаются. Но сама последовательность символов в конкретном строковом объекте не подлежит изменению после его создания. Для создания строк, которые нельзя изменить, в C# предусмотрен класс StringBuilder, находящийся в пространстве имен System. Text. Но на практике для этой цели чаще используется тип string, а не класс StringBuilder. Класс String Класс String определен в пространстве имен System. В нем реализуются следующие интерфейсы: IComparable, IComparable Конструкторы класса String В классе String определено несколько конструкторов, позволяющих создавать строки самыми разными способами. Для создания строки из символьного массива служит один из следующих конструкторов. public String(char[ ] value) public String(char[ ] value, int startlndex, int length) Первая форма конструктора позволяет создать строку, состоящую из символов массива value. А во второй форме для этой цели из массива value извлекается определенное количество символов (length), начиная с элемента, указываемого по индексу startlndex. С помощью приведенного ниже конструктора можно создать строку, состоящую из отдельного символа, повторяющегося столько раз, сколько потребуется: public String(char с, int count) где с обозначает повторяющийся символ; a count – количество его повторений. Кроме того, строку можно создать по заданному указателю на символьный массив, используя один из следующих конструкторов. public String(char* value) public String(char* value, int startlndex, int length) Первая форма конструктора позволяет создать строку из символов, доступных из массива по указателю value . При этом предполагается, что массив, доступный по указателю value , завершается пустым символом, обозначающим конец строки. А во второй форме конструктора для этой цели из массива, доступного по указателю value , извлекается определенное количество символов (length), начиная с элемента, указываемого по индексу startlndex. В этих конструкторах применяются указатели, поэтому их можно использовать только в небезопасном коде. И наконец, строку можно построить по заданному указателю на байтовый массив, используя один из следующих конструкторов. public String(sbyte* value) public String(sbyte* value , int startlndex, int length) public String(sbyte* value , int startlndex, int length, Encoding enc) Первая форма конструктора позволяет построить строку из отдельных байтов символов, доступных из массива по указателю value. При этом предполагается, что массив, доступный по указателю value, завершается признаком конца строки. Во второй форме конструктора для этой цели из массива, доступного по указателю value, извлекается определенное количество байтов символов (length), начиная с элемента, указываемого по индексу startlndex. А третья форма конструктора позволяет указать количество кодируемых байтов. Класс Encoding находится в пространстве имен System. Text. В этих конструкторах применяются указатели, и поэтому их можно использовать только в небезопасном коде. При объявлении строкового литерала автоматически создается строковый объект. Поэтому для инициализации строкового объекта зачастую оказывается достаточно присвоить ему строковый литерал, как показано ниже. string str = "новая строка"; Поле, индексатор и свойство класса String В классе String определено единственное поле. public static readonly string Empty Поле Empty обозначает пустую строку, т.е. такую строку, которая не содержит символы. Этим оно отличается от пустой ссылки типа String, которая просто делается на несуществующий объект. Помимо этого, в классе String определен единственный индексатор, доступный только для чтения. public char this[int index] { get; } Этот индексатор позволяет получить символ по указанному индексу. Индексация строк, как и массивов, начинается с нуля. Объекты типа String отличаются постоянством и не изменяются, поэтому вполне логично, что в классе String поддерживается индексатор, доступный только для чтения. И наконец, в классе String определено единственное свойство, доступное только для чтения. public int Length { get; } Свойство Length возвращает количество символов в строке. Операторы класса String В классе String перегружаются два следующих оператора: == и ! =. Оператор == служит для* проверки двух символьных строк на равенство. Когда оператор == применяется к ссылкам на объекты, он обычно проверяет, делаются ли обе ссылки на один и тот же объект. А когда оператор == применяется к ссылкам на объекты типа String, то на предмет равенства сравнивается содержимое самих строк. Это же относится и к оператору ! =. Когда он применяется к ссылкам на объекты типа String, то на предмет неравенства сравнивается содержимое самих строк. В то же время другие операторы отношения, в том числе < и >=, сравнивают ссылки на объекты типа String таким же образом, как и на объекты других типов. А для того чтобы проверить, является ли одна строка больше другой, следует вызвать метод Compare (), определенный в классе String. Как станет ясно дальше, во многих видах сравнения символьных строк используются сведения о культурной среде. Но это не относится к операторам = = и ! =. Ведь они просто сравнивают порядковые значения символов в строках. (Иными словами, они сравнивают двоичные значения символов, не видоизмененные нормами культурной среды, т.е. региональными стандартами.) Следовательно, эти операторы выполняют сравнение строк без учета регистра и настроек культурной среды. Сравнение строк Вероятно, из всех операций обработки символьных строк чаще всего выполняется сравнение одной строки с другой. Прежде чем рассматривать какие‑либо методы сравнения строк, следует подчеркнуть следующее: сравнение строк может быть выполнено в среде .NET Framework двумя основными способами. Во‑первых, сравнение может отражать обычаи и нормы отдельной культурной среды, которые зачастую представляют собой настройки культурной среды, вступающие в силу при выполнении программы. Это стандартное поведение некоторых, хотя и не всех методов сравнения. И во‑вторых, сравнение может быть выполнено независимо от настроек культурной среды только по порядковым значениям символов, составляющих строку. Вообще говоря, при сравнении строк без учета культурной среды используется лексикографический порядок (и лингвистические особенности), чтобы определить, является ли одна строка больше, меньше или равной другой строке. При порядковом сравнении строки просто упорядочиваются на основании невидоизмененного значения каждого символа. ПРИМЕЧАНИЕ В силу отличий способов сравнения строк с учетом культурной среды и порядкового сравнения, а также последствий каждого такого сравнения настоятельно рекомендуется руководствоваться лучшими методиками, предлагаемыми в настоящее время корпорацией Microsoft. Ведь выбор неверного способа сравнения строк может привести к неправильной работе программы, когда она эксплуатируется в среде, отличающей от той, в которой она разработана. Выбор способа сравнения символьных строк представляет собой весьма ответственное решение. Как правило и без всякий исключений, следует выбирать сравнение строк с учетом культурной среды, если это делается для целей отображения результата пользователю (например, для вывода на экран ряда строк, отсортированных в лексикографическом порядке). Но если строки содержат фиксированную информацию, не предназначенную для видоизменения с учетом отличий в культурных средах, например, имя файла, ключевое слово, адрес веб‑сайта или значение, связанное с обеспечением безопасности, то следует выбрать порядковое сравнение строк. Разумеется, особенности конкретного разрабатываемого приложения будут диктовать выбор подходящего способа сравнения символьных строк. В классе String предоставляются самые разные методы сравнения строк, перечисленные в табл. 22.1. Наиболее универсальным среди них является метод Compare (). Он позволяет сравнивать две строки полностью или частично, с учетом или без учета регистра, способа сравнения, определяемого параметром типа StringComparison, а также сведений о культурной среде, предоставляемых с помощью параметра типа Culturelnfo. Те перегружаемые варианты метода Compare (), которые не содержат параметр типа StringComparison, выполняют сравнение символьных строк с учетом регистра и культурной среды. А в тех перегружаемых его вариантах, которые не содержат параметр типа Culturelnfo, сведения о культурной среде определяются текущей средой выполнения. В примерах программ, приведенных в этой главе, параметр типа Culturelnfo не используется, а большее внимание уделяется использованию параметра типа StringComparison. Таблица 22.1. Методы сравнения символьных строк Метод Назначение public static int Сравнивает строку strA со строкой strB. Возвращает поло Compare(string strA, жительное значение, если строка strA больше строки strB ; string strB) отрицательное значение, если строка strA меньше строки strB ; и нуль, если строки strA и strB равны. Сравнение выполняется с учетом регистра и культурной среды public static int Сравнивает строку strA со строкой strB. Возвращает поло Compare(string strA, жительное значение, если строка strA больше строки strB ; string strB, bool отрицательное значение, если строка strA меньше строки ignoreCase) strB ; и нуль, если строки strA и strB равны. Если параметр ignoreCase принимает логическое значение true, то при сравнении не учитываются различия между прописным и строчным вариантами букв. В противном случае эти различия учитываются. Сравнение выполняется с учетом культурной среды public static int Сравнивает строку strA со строкой strB. Возвращает положи Compare(string тельное значение, если строка strA больше строки strB ; отрица strA, string strB, тельное значение, если строка strA меньше строки strB‑, и нуль, StringComparison если строки strA и strB равны. Параметр comparisonType comparisonType) определяет конкретный способ сравнения строк public static int. Сравнивает строку strA со строкой strB, используя информа Compare(string цию о культурной среде, определяемую параметром culture. strA, string strB, Возвращает положительное значение, если строка strA боль bool ignoreCase, ше строки strB ; отрицательное значение, если строка strA Culturelnfo culture) меньше строки strB ; и нуль, если строки strA и strB равны. Если параметр ignoreCase принимает логическое значение true, то при сравнении не учитываются различия между прописным и строчным вариантами букв. В противном случае эти различия учитываются. Класс Culturelnfo определен в пространстве имен System.Globalization Метод Назначение public static int Сравнивает части строк strA и strB. Сравнение начинается Compare(string strA, со строковых элементов strA[ indexA] и strB[indexB] int indexA, string и включает количество символов, определяемых параметром strB, int indexB, length. Метод возвращает положительное значение, если int length) часть строки strA больше части строки strB] отрицательное значение, если часть строки strA меньше части строки strB ; и нуль, если сравниваемые части строк strA и strB равны. Сравнение выполняется с учетом регистра и культурной среды public static int Сравнивает части строк strA и strB. Сравнение начинается Compare(string strA, СО строковых элементов str А[ indexA] и strB[indexB] int indexA, string и включает количество символов, определяемых параметром strB, int indexB, length. Метод возвращает положительное значение, если int length, bool часть строки strA больше части строки strB ; отрицатель ignoreCase) ное значение, если часть строки strA меньше части строки strB ; и нуль, если сравниваемые части строк strA и strB равны. Если параметр ignoreCase принимает логическое значение true, то при сравнении не учитываются различия между прописным и строчным вариантами букв. В противном случае эти различия учитываются. Сравнение выполняется с учетом культурной среды public static int Сравнивает части строк strA и strB. Сравнение начинается Compare(string со строковых элементов strA[ indexA] и strB[indexB] strA, int indexA, и включает количество символов, определяемых параметром string strB, int length. Метод возвращает положительное значение, если indexB, int length, часть строки strA больше части строки strB ; отрицатель StringComparison ное значение, если часть строки strA меньше части строки comparisonType) strB ; и нуль, если сравниваемые части строк strA и strB равны. Параметр comparisonType определяет конкретный способ сравнения строк |