Текст книги "Полное руководство. С# 4.0"
Автор книги: Герберт Шилдт
Жанр:
Программирование
сообщить о нарушении
Текущая страница: 48 (всего у книги 58 страниц)
Во многих классах приходится реализовывать интерфейс IComparable или IComparable, поскольку он позволяет сравнивать один объект с другим, используя различные методы, определенные в среде .NET Framework. Интерфейсы IComparable и IComparable были представлены в главе 18, где они использовались в примерах программ для сравнения двух объектов, определяемых параметрами обобщенного типа. Кроме того, они упоминались при рассмотрении класса Array ранее в этой гла ве. Но поскольку эти интерфейсы имеют особое значение и применяются во многих случаях, то ниже приводится их краткое описание.
Интерфейс IComparable реализуется чрезвычайно просто, потому что он состоит всего лишь из одного метода. int CompareTo(object obj)
В этом методе значение вызывающего объекта сравнивается со значением объекта, определяемого параметром obj. Если значение вызывающего объекта больше, чем у объекта obj, то возвращается положительное значение; если оба значения равны – нулевое значение, а если значение вызывающего объекта меньше, чем у объекта obj, – отрицательное значение.
Обобщенный вариант интерфейса IComparable объявляется следующим об разом. public interface IComparable
В данном варианте тип сравниваемых данных передается параметру Т в качестве ар гумента типа. В силу этого объявление метода CompareTo() претерпевает изменения и выглядит так, как показано ниже. int CompareTo(Т other)
В этом объявлении тип данных, которыми оперирует метод CompareTo(), может быть указан явным образом. Следовательно, интерфейс IComparable обеспечи вает типовую безопасность. Именно по этой причине он теперь считается более пред почтительным в программировании на С#, чем интерфейс IComparable. Интерфейс IEquatable
Интерфейс IEquatable
Этот метод возвращает логическое значение true, если значение вызывающего объекта оказывается равным значению другого объекта other, в противном случае – логическое значение false.
Интерфейс IEquatable реализуется в нескольких классах и структурах среды .NET Framework, включая структуры числовых типов и класс String. Для реализа ции интерфейса IEquatable обычно требуется также переопределять методы Equals(Object) и GetHashCode(), определенные в классе Object. Интерфейс IConvertible
Интерфейс IConvertible реализуется в структурах всех типов значений, String и DateTime. В нем определяются различные преобразования типов. Реализовывать этот интерфейс в создаваемых пользователем классах, как правило, не требуется. Интерфейс ICloneable
Реализовав интерфейс ICloneable, можно создать все условия для копирования объекта. В интерфейсе ICloneable определен только один метод, Clone(), объявле ние которого приведено ниже. object Clone()
В этом методе создается копия вызывающего объекта, а конкретная его реализация зависит от способа создания копии объекта. Вообще говоря, существуют две разно видности копий объектов: полная и неполная. Если создается полная копия, то ко пия совершенно не зависит от оригинала. Так, если в исходном объекте содержится ссылка на другой объект О, то при его копировании создается также копия объекта О. А при создании неполной копии осуществляется копирование одних только членов, но не объектов, на которые эти члены ссылаются. Так, после создания неполной ко пии объекта, ссылающегося на другой объект О, копия и оригинал будут ссылаться на один и тот же объект О, причем любые изменения в объекте О будут оказывать влия ние как на копию, так и на оригинал. Как правило, метод Clone() реализуется для получения полной копии. А неполные копии могут быть созданы с помощью метода MemberwiseClone(), определенного в классе Object.
Ниже приведен пример программы, в которой демонстрируется применение ин терфейса ICloneable. В ней создается класс Test, содержащий ссылку на объект клас са X. В самом классе Test используется метод Clone() для создания полной копии. // Продемонстрировать применение интерфейса ICloneable. using System; class X { public int a; public X(int x) { a = x; } } class Test : ICloneable { public X о; public int b; public Test(int x, int y) { о = new X(x); b = y; } public void Show(string name) { Console.Write("Значения объекта " + name + ": "); Console.WriteLine("о.a: {0}, b: {1}", o.a, b); } // Создать полную копию вызывающего объекта. public object Clone() { Test temp = new Test(o.a, b); return temp; } } class CloneDemo { static void Main() { Test ob1 = new Test(10, 20); obi.Show("ob1"); Console.WriteLine("Сделать объект ob2 копией объекта оb1."); Test ob2 = (Test) ob1.Clone(); ob2.Show("ob2"); Console.WriteLine("Изменить значение оb1.о.а на 99, " + " а значение оb1.b – на 88."); оb1.о.а = 99; оb1.b = 88; оb1.Show("оb1"); ob2.Show("оb2"); } }
Ниже приведен результат выполнения этой программы. Значения объекта оb1: о.а: 10, b: 20 Сделать объект оb2 копией объекта оb1. Значения объекта оb2: о.а: 10, b: 20 Изменить значение оb1.о.а на 99, а значение оb1.b – на 88. Значения объекта оb1: о.а: 99, b: 88 Значения объекта оb2: о.а: 10, b: 20
Как следует из результата выполнения приведенной выше программы, объект оb2 является копией объекта оb1, но это совершенно разные объекты. Изменения в одном из них не оказывают никакого влияния на другой. Это достигается конструированием нового объекта типа Test, который выделяет новый объект типа X для копирования. При этом новому экземпляру объекта типа X присваивается такое же значение, как и у объекта типа X в оригинале.
Для получения неполной копии достаточно вызвать метод MemberwiseClone(), определяемый в классе Object из метода Clone(). В качестве упражнения попробуйте заменить метод Clone() в предыдущем примере программы на следующий его вариант. // Сделать неполную копию вызывающего объекта. public object Clone() { Test temp = (Test) MemberwiseClone(); return temp; }
После этого изменения результат выполнения данной программы будет выглядеть следующим образом. Значения объекта оb1: о.а: 10, b: 20 Сделать объект оb2 копией объекта оb1. Значения объекта оb2: о.а: 10, b: 20 Изменить значение оb1.о.а на 99, а значение оb1.b – на 88. Значения объекта оb1: о.а: 99, b: 88 Значения объекта оb2: о.а: 99, b: 20
Как видите, обе переменные экземпляра о в объектах оb1 и оb2 ссылаются на один и тот же объект типа X. Поэтому изменения в одном объекте оказывают влияние на другой. Но в то же время поля b типа int в каждом из них разделены, поскольку типы значений недоступны по ссылке. Интерфейсы IFormatProvider и IFormattable
В интерфейсе IFormatProvider определен единственный метод GetFormat(), ко торый возвращает объект, определяющий форматирование данных в удобочитаемой форме текстовой строки. Ниже приведена общая форма метода GetFormat(): object GetFormat(Type formatType)
где formatType – это объект, получаемый для форматирования. Интерфейс IFormattable поддерживает форматирование выводимых результатов в удобочитаемой форме. В нем определен следующий метод: string ToString(string format, IFormatProvider formatProvider)
где format обозначает инструкции для форматирования, a formatProvider – поставщик формата.
ПРИМЕЧАНИЕ Подробнее о форматировании речь пойдет в главе 22. Интерфейсы IObservable и IObserver
В версию .NET Framework 4.0 добавлены еще два интерфейса, поддерживающие шаблон наблюдателя: IObservable и IObserver. В шаблоне наблюдателя один класс (в роли наблюдаемого) предоставляет уведомления другому классу (в роли наблюдателя). С этой целью объект наблюдаемого класса регистрирует объект наблю дающего класса. Для регистрации наблюдателя вызывается метод Subscribe(), ко торый определен в интерфейсе IObservable и которому передается объект типа IObserver, принимающий уведомление. Для получения уведомлений можно зарегистрировать несколько наблюдателей. А для отправки уведомлений всем за регистрированным наблюдателям применяются три метода, определенные в интер фейсе IObserver. Так, метод OnNext() отправляет данные наблюдателю, метод OnError() сообщает об ошибке, а метод OnCompleted() указывает на то, что наблю даемый объект прекратил отправку уведомлений.
ГЛАВА 22. Строки и форматирование
В этой главе рассматривается класс String, положен ный в основу встроенного в C# типа string. Как из вестно, обработка символьных строк является неот ъемлемой частью практически всех программ. Именно по этой причине в классе String определяется обширный ряд методов, свойств и полей, обеспечивающих наиболее полное управление процессом построения символьных строк и манипулирования ими. С обработкой строк тесно связано форматирование данных в удобочитаемой форме. Используя подсистему форматирования, можно отфор матировать данные всех имеющихся в C# числовых типов, а также дату, время и перечисления. Строки в C
Вопросы обработки строк уже обсуждались в главе 7, и поэтому не стоит повторяться. Вместо этого целесообраз но дать краткий обзор реализации символьных строк в С#, прежде чем переходить к рассмотрению класса String.
Во всех языках программирования строка представляет собой последовательность символов, но конкретная ее реа лизация отличается в разных языках. В некоторых языках программирования, например в C++, строки представля ют собой массивы символов, тогда как в C# они являются объектами встроенного типа данных string. Следова тельно, string является ссылочным типом. Более того, string – это имя стандартного для среды .NET строково го типа System.String. Это означает, что в C# строке как объекту доступны все методы, свойства, поля и операторы, определенные в классе String.
После создания строки последовательность составляющих ее символов не может быть изменена. Благодаря этому ограничению строки реализуются в C# более эффек тивно. И хотя такое ограничение кажется на первый взгляд серьезным препятствием, на самом деле оно таковым не является. Когда требуется получить строку как разно видность уже существующей строки, достаточно создать новую строку, содержащую требующиеся изменения, и "отвергнуть" исходную строку, если она больше не нужна. А поскольку ненужные строковые объекты автоматически утилизируются средствами "сборки мусора", то беспокоиться о дальнейшей судьбе "отвергнутых" строк не при ходится. Следует, однако, подчеркнуть, что переменные ссылок на строки могут, безу словно, изменить объект, на который они ссылаются. Но сама последовательность сим волов в конкретном строковом объекте не подлежит изменению после его создания.
Для создания строк, которые нельзя изменить, в C# предусмотрен класс StringBuilder, находящийся в пространстве имен System.Text. Но на практике для этой цели чаще используется тип string, а не класс StringBuilder. Класс String
Класс String определен в пространстве имен System. В нем реализуются следую щие интерфейсы: IComparable, IComparable, ICloneable, IConvertible, IEnumerable, IEnumerable и IEquatable. Кроме того, String – герметичный класс, а это означает, что он не может наследоваться. В классе String предоставляются все необходимые функциональные возможности для обработки сим вольных строк в С#. Он служит основанием для встроенного в C# типа string и явля ется составной частью среды .NET Framework. В последующих разделах представлено подробное описание класса String. Конструкторы класса String
В классе String определено несколько конструкторов, позволяющих создавать строки самыми разными способами. Для создания строки из символьного массива служит один из следующих конструкторов. public String(char[ ] value) public String(char[ ] value, int startIndex, int length)
Первая форма конструктора позволяет создать строку, состоящую из символов мас сива value. А во второй форме для этой цели из массива value извлекается опреде ленное количество символов (length), начиная с элемента, указываемого по индексу startIndex.
С помощью приведенного ниже конструктора можно создать строку, состоящую из отдельного символа, повторяющегося столько раз, сколько потребуется: public String(char с, int count)
где с обозначает повторяющийся символ; a count – количество его повторений.
Кроме того, строку можно создать по заданному указателю на символьный массив, используя один из следующих конструкторов. public String(char* value) public String(char* value, int startIndex, int length)
Первая форма конструктора позволяет создать строку из символов, доступных из массива по указателю value. При этом предполагается, что массив, доступный по указателю value, завершается пустым символом, обозначающим конец строки. А во второй форме конструктора для этой цели из массива, доступного по указателю value, извлекается определенное количество символов (length), начиная с элемента, указываемого по индексу startIndex. В этих конструкторах применяются указатели, поэтому их можно использовать только в небезопасном коде.
И наконец, строку можно построить по заданному указателю на байтовый массив, используя один из следующих конструкторов. public String(sbyte* value) public String(sbyte* value, int startIndex, int length) public String(sbyte* value, int startIndex, int length, Encoding enc)
Первая форма конструктора позволяет построить строку из отдельных байтов сим волов, доступных из массива по указателю value. При этом предполагается, что мас сив, доступный по указателю value, завершается признаком конца строки. Во второй форме конструктора для этой цели из массива, доступного по указателю value, из влекается определенное количество байтов символов (length), начиная с элемента, указываемого по индексу startIndex. А третья форма конструктора позволяет ука зать количество кодируемых байтов. Класс 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, а также сведений о культурной среде, предоставляемых с помощью параметра типа CultureInfo. Те перегружаемые варианты метода Compare(), которые не содержат параметр типа StringComparison, выполняют сравнение символьных строк с учетом регистра и культурной среды. А в тех перегружаемых его вариантах, которые не со держат параметр типа CultureInfo, сведения о культурной среде определяются теку щей средой выполнения. В примерах программ, приведенных в этой главе, параметр типа CultureInfo не используется, а большее внимание уделяется использованию параметра типа StringComparison.
Таблица 22.1. Методы сравнения символьных строк Метод Назначение public static int Compare(string strA, string strB) Сравнивает строку strA со строкой strB. Возвращает положительное значение, если строка strA больше строки strB; отрицательное значение, если строка strA меньше строки strB; и нуль, если строки strA и strB равны. Сравнение выполняется с учетом регистра и культурной среды public static int Compare(string strA, string strB, bool ignoreCase) Сравнивает строку strA со строкой strB. Возвращает положительное значение, если строка strA больше строки strB; отрицательное значение, если строка strA меньше строки strB; и нуль, если строки strA и strB равны. Если параметр ignoreCase принимает логическое значение true, то при сравнении не учитываются различия между прописным и строчным вариантами букв. В противном случае эти различия учитываются. Сравнение выполняется с учетом культурной среды public static int Compare(string strA, string strB, StringComparison comparisonType) Сравнивает строку strA со строкой strB. Возвращает положительное значение, если строка strA больше строки strB; отрицательное значение, если строка strA меньше строки strB; и нуль, если строки strA и strB равны. Параметр comparisonType определяет конкретный способ сравнения строк public static int Compare(string strA, string strB, bool ignoreCase, Culturelnfo culture) Сравнивает строку strA со строкой strB, используя информацию о культурной среде, определяемую параметром culture. Возвращает положительное значение, если строка strA больше строки strB; отрицательное значение, если строка strA меньше строки strB; и нуль, если строки strA и strB равны. Если параметр ignoreCase принимает логическое значение true, то при сравнении не учитываются различия между прописным и строчным вариантами букв. В противном случае эти различия учитываются. Класс CultureInfo определен в пространстве имен System.Globalization public static int Compare(string strA, int indexA, string strB, int indexB, int length) Сравнивает части строк strA и strB. Сравнение начинается со строковых элементов strA[indexA] и strB[indexB] и включает количество символов, определяемых параметром length. Метод возвращает положительное значение, если часть строки strA больше части строки strB; отрицательное значение, если часть строки strA меньше части строки strB; и нуль, если сравниваемые части строк strA и strB равны. Сравнение выполняется с учетом регистра и культурной среды public static int Compare(string strA, int IndexA, string strB, int indexB, int length, bool ignoreCase) Сравнивает части строк strA и strB. Сравнение начинается со строковых элементов strA[indexA] и strB[indexB] и включает количество символов, определяемых параметром length. Метод возвращает положительное значение, если часть строки strA больше части строки strB; отрицательное значение, если часть строки strA меньше части строки strB; и нуль, если сравниваемые части строк strA и strB равны. Если параметр ignoreCase принимает логическое значение true, то при сравнении не учитываются различия между прописным и строчным вариантами букв. В противном случае эти различия учитываются. Сравнение выполняется с учетом культурной среды public static int Compare(string strA, int indexA, string strB, int indexB, int length, StringComparison comparisonType) Сравнивает части строк strA и strB. Сравнение начинается со строковых элементов strA[indexA] и strB[indexB] и включает количество символов, определяемых параметром length. Метод возвращает положительное значение, если часть строки strA больше части строки strB; отрицательное значение, если часть строки strA меньше части строки strB; и нуль, если сравниваемые части строк strA и strB равны. Параметр comparisonType определяет конкретный способ сравнения строк public static int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignoreCase, CultureInfo culture) Сравнивает части строк strA и strB, используя инфор мацию о культурной среде, определяемую параметром culture. Сравнение начинается со строковых элементов strA[indexA] и strB[indexB] и включает количество символов, определяемых параметром length. Метод возвращает положительное значение, если часть строки strA больше части строки strB; отрицательное значение, если часть строки strA меньше части строки strB; и нуль, если сравниваемые части строк strA и strB равны. Если параметр ignoreCase принимает логическое значение true, то при сравнении не учитываются различия между прописным и строчным вариантами букв. В противном случае эти различия учитываются. Класс CultureInfo определен в пространстве имен System.Globalization public static int Compare(string strA, string strB, Culturelnfo culture, CompareOptions options) Сравнивает строку strA со строкой strB, используя информацию о культурной среде, обозначаемую параметром culture, а также варианты сравнения, передаваемые в качестве параметра options. Возвращает положительное значение, если строка strA больше строки strB; отрицательное значение, если строка strA меньше строки strB; и нуль, если строки strA и strB равны. Классы CultureInfo и CompareOptions определены в пространстве имен System.Globalization public static int Compare(string strA, int indexA, string strB, int indexB, int length, CultureInfo culture, CompareOptions options) Сравнивает части строк strA и strB, используя информацию о культурной среде, обозначаемую параметром culture, а также варианты сравнения, передаваемые в качестве параметра options. Сравнение начинается со строковых элементов strA[indexA] и strB[indexB] и включает количество символов, определяемых параметром length. Метод возвращает положительное значение, если часть строки strA больше части строки strB; отрицательное значение, если часть строки strA меньше части строки strB; и нуль, если сравниваемые части строк strA и strB равны. Классы CultureInfo и CompareOptions определены в пространстве имен System.Globalization public static int CompareOrdinal(string strA, string strB) Сравнивает строку strA со строкой strB независимо от культурной среды, языка и региональных стандартов. Возвращает положительное значение, если строка strA больше строки strB; отрицательное значение, если строка strA меньше строки strB; и нуль, если строки strA и strB равны public static int CompareOrdinal(string strA, int indexA, string strB, int IndexB, int count) Сравнивает части строк strA и strB независимо от культурной среды, языка и региональных стандартов. Сравнение начинается со строковых элементов strA[indexA] и strB[indexB] и включает количество символов, определяемых параметром count. Метод возвращает положительное значение, если часть строки strA больше части строки strB; отрицательное значение, если часть строки strA меньше части строки strB; и нуль, если сравниваемые части строк strA и strB равны public int CompareTo(object value) Сравнивает вызывающую строку со строковым представлением объекта value. Возвращает положительное значение, если вызывающая строка больше строки value; отрицательное значение, если вызывающая строка меньше строки value; и нуль, если сравниваемые строки равны public int CompareTo(string strB) Сравнивает вызывающую строку со строкой strB. Возвращает положительное значение, если вызывающая строка больше строки strB; отрицательное значение, если вызывающая строка меньше строки strB; и нуль, если сравниваемые строки равны public override bool Equals(object obj) Возвращает логическое значение true, если вызывающая строка содержит ту же последовательность символов, что и строковое представление объекта obj. Выполняется порядковое сравнение с учетом регистра, но без учета культурной среды public bool Equals(string value) Возвращает логическое значение true, если вызывающая строка содержит ту же последовательность символов, что и строка value. Выполняется порядковое сравнение с учетом регистра, но без учета культурной среды public bool Equals(string value, StringComparison comparisonType) Возвращает логическое значение true, если вызывающая строка содержит ту же последовательность символов, что и строка value. Параметр comparisonType определяет конкретный способ сравнения строк public static bool Equals(string a, string b) Возвращает логическое значение true, если строка а содержит ту же последовательность символов, что и строка b. Выполняется порядковое сравнение с учетом регистра, но без учета культурной среды public static bpol Equals(string a, string b, StringComparison comparisonType) Возвращает логическое значение true, если строка а содержит ту же последовательность символов, что и строка b. Параметр comparisonType определяет конкретный способ сравнения строк
Тип StringComparison представляет собой перечисление, в котором определяются значения, приведенные в табл. 22.2. Используя эти значения, можно организовать срав нение строк, удовлетворяющее потребностям конкретного приложения. Следователь но, добавление параметра типа StringComparison расширяет возможности метода Compare() и других методов сравнения, например, Equals(). Это дает также возмож ность однозначно указывать способ предполагаемого сравнения строк. В силу имеющих отличий между сравнением строк с учетом культурной среды и порядковым сравнени ем очень важно быть предельно точным в этом отношении. Именно по этой причине в примерах программ, приведенных в данной книге, параметр типа StringComparison явно указывается в вызовах тех методов, в которых он поддерживается.
Таблица 22.2. Значения, определяемые в перечислении StringComparison Значение Описание CurrentCulture Сравнение строк производится с использованием текущих настроек параметров культурной среды CurrentCultureIgnoreCase Сравнение строк производится с использованием текущих настроек параметров культурной среды, но без учета регистра InvariantCulture Сравнение строк производится с использованием неизменяемых, т.е. универсальных данных о культурной среде InvariantCultureIngoreCase Сравнение строк производится с использованием неизменяемых, т.е. универсальных данных о культурной среде и без учета регистра Ordinal Сравнение строк производится с использованием порядковых значений символов в строке. При этом лексикографический порядок может нарушиться, а условные обозначения, принятые в отдельной культурной среде, игнорируются OrdinalIgnoreCase Сравнение строк производится с использованием порядковых значений символов в строке, но без учета регистра. При этом лексикографический порядок может нарушиться, а условные обозначения, принятые в отдельной культурной среде, игнорируются
В любом случае метод Compare() возвращает отрицательное значение, если первая сравниваемая строка оказывается меньше второй; положительное значение, если пер вая сравниваемая строка больше второй; и наконец, нуль, если обе сравниваемые стро ки равны. Несмотря на то что метод Compare() возвращает нуль, если сравниваемые строки равны, для определения равенства символьных строк, как правило, лучше поль зоваться методом Equals() иди же оператором = =. Дело в том, что метод Compare() определяет равенство сравниваемых строк на основании порядка их сортировки. Так, если выполняется сравнение строк с учетом культурной среды, то обе строки могут оказаться одинаковыми по порядку их сортировки, но не равными по существу. По умолчанию равенство строк определяется в методе Equals(), исходя из порядковых значений символов и без учета культурной среды. Следовательно, по умолчанию обе строки сравниваются в этом методе на абсолютное, посимвольное равенство подобно тому, как это делается в операторе = =.