Compareto c как работает
Перейти к содержимому

Compareto c как работает

  • автор:

Урок 21. Функции сравнения строк C#

21-я часть учебника по основам языка C# продолжает изучение функциональности управления строками, предоставляемой классом String. В данной статье рассматриваются методы, доступные для сравнения содержимого строк.

Операторы равенства и неравенства

В более ранней части учебника по основам C# мы обсуждали равенство ( == ) и неравенство (!=) — реляционные операторы. Эти операторы позволяют производить точное сравнение двух строк с учетом регистра. В случае оператора равенства, если строки совпадают, результирующее логическое значение равно true. Если они отличаются, результат будет false. Оператор неравенства возвращает противоположный результат, как показано ниже:

Эти операторы полезны, но имеют ограничения. Они не позволяют вам рассматривать равенство двух строк, которые совпадают во всех, кроме регистра символов, к примеру. Они также не позволяют определить, что одна строка больше другой. В этой статье описываются методы, которые предоставляются для решения данных проблем.

Относительное сравнение

Метод CompareTo

Платформа .NET framework предоставляет метод CompareTo для многих типов данных, включая строки. Он позволяет сравнивать два значения и возвращает результат, который указывает не только на то, равны ли они, но и на то, что больше, когда они не равны. Метод учитывает и другую информацию при сравнении строк. Например, японские символы катаканы могут быть написаны двумя способами: в половину ширины или в полную ширину. Метод CompareTo считает, что символы, записанные как полная ширина, равны тем же символам половины ширины. Та же культурная информация используется для определения того, какая строка больше.

Метод CompareTo работает с существующей строкой. Строка, с которой она будет сравниваться, передается параметру. Метод возвращает целое число, обозначающее результат сравнения следующим образом:

Это можно уточнить на примере:

Примечание: поскольку этот метод вызывается для существующего экземпляра string, то если строка имеет значение null, возникает исключение:

Метод Compare

Функция Compare является статическим методом класса string. Он предоставляет аналогичную функциональность CompareTo, но позволяет указать больше опций. В качестве статического члена класса string обе строки передаются в качестве параметров.

Сравнение значений Null

Метод CompareTo вызывает исключение, если проверяемая строка имеет значение null, так как объект null не имеет доступных методов. Однако, поскольку метод Compare статичен, можно сравнивать пустые строки. Чувствительность к регистру

Метод Compare позволяет вам решать, выполнять ли сравнения с учетом регистра или без учета регистра. Различия между прописными и строчными буквами применяются в соответствии с настройками языка пользователя. Чтобы определить, следует ли использовать сравнение с учетом регистра, используется третий логический параметр. Если значение true, регистры игнорируются. Если false, то эффект будет таким же, как и отсутствие параметра вообще.

Этот пример предполагает английские настройки:

Метод Compare включает в себя перегруженные версии, позволяющие сравнивать строки с использованием дополнительных настроек международного языка, а также опции сравнения частей строк. Они выходят за рамки этого учебника, но их стоит изучить. Дополнительные сведения можно найти в MSDN.

Метод CompareOrdinal

Статический метод Compareordinal позволяет производить сравнение двух строк с учетом регистра. Он отличается от Compare тем, что result сравнения основан на числовых значениях Юникода для каждого символа. Поскольку важность символов в культурном контексте может отличаться от фиксированного числового порядка Юникода, при сравнении с использованием этого метода могут быть получены различные результаты. Это показано в следующем примере, который предполагает английскую конфигурацию Великобритании:

Метод Equals

Ну и рассмотрим метод Equals для полноты урока. Он возвращает логический result, указывающий, совпадают ли две строки, подобно оператору равенства (==). Метод может использоваться для объекта string с одним параметром или в качестве статического члена с двумя параметрами для сравниваемых строк.

Метод IsNullOrEmpty .NET 2.0

Иногда необходимо проверить, является ли строка пустой или неопределенной (null). При использовании .NET 1.1 для этого потребуется два теста. В .NET framework 2.0 появился новый статический метод isnullorempty, который выполняет оба теста с помощью одной инструкции. Метод возвращает true, если строка пустая или null.


Автор этого материала — я — Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML — то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, Уроки по си шарп, си шарп, string, сравнение

Compareto c как работает

Большинство встроенных в .NET классов коллекций и массивы поддерживают сортировку. С помощью одного метода, который, как правило, называется Sort() можно сразу отсортировать по возрастанию весь набор данных. Например:

Однако метод Sort по умолчанию работает только для наборов примитивных типов, как int или string. Для сортировки наборов сложных объектов применяется интерфейс IComparable . Он имеет всего один метод:

Метод CompareTo предназначен для сравнения текущего объекта с объектом, который передается в качестве параметра object? o . На выходе он возвращает целое число, которое может иметь одно из трех значений:

Меньше нуля. Значит, текущий объект должен находиться перед объектом, который передается в качестве параметра

Равен нулю. Значит, оба объекта равны

Больше нуля. Значит, текущий объект должен находиться после объекта, передаваемого в качестве параметра

Например, имеется класс Person:

Здесь в качестве критерия сравнения выбрано свойство Name объекта Person. Поэтому при сравнении здесь фактически идет сравнение значения свойства Name текущего объекта и свойства Name объекта, переданного через параметр. Если вдруг объект не удастся привести к типу Person, то выбрасывается исключение.

И в данном случае мы получим следующий консольный вывод:

Интерфейс IComparable имеет обобщенную версию, поэтому мы могли бы сократить и упростить его применение в классе Person:

Аналогичным образом мы мошли сравнивать по возрасту:

Применение компаратора

Кроме интерфейса IComparable платформа .NET также предоставляет интерфейс IComparer:

Метод Compare предназначен для сравнения двух объектов o1 и o2. Он также возвращает три значения, в зависимости от результата сравнения: если первый объект больше второго, то возвращается число больше 0, если меньше — то число меньше нуля; если оба объекта равны, возвращается ноль.

Создадим компаратор объектов Person. Пусть он сравнивает объекты в зависимости от длины строки — значения свойства Name:

В данном случае используется обобщенная версия интерфейса IComparer, чтобы не делать излишних преобразований типов. Применение компаратора:

Сравнение произвольных типов в C#. Интерфейс IComparable

Как нам уже известно, для сравнения переменных примитивных типов мы можем использовать различные логические операторы. Однако, при написании своих собственных программ мы далеко не всегда используем только примитивные типы данных — мы можем создавать собственные классы с произвольными наборами свойств. И, в этом случае, мы уже не можем просто воспользоваться логическими операторами для сравнения, так как платформа .NET просто не знает как сравнивать произвольные классы (и можно ли их сравнивать, в принципе). Для сравнения двух объектов произвольного типа мы можем, например, воспользоваться возможностью перегрузки операторов, а можем использовать интерфейс IComparable .

Рабочий пример класса для сравнения

Итак, пусть у нас имеется класс, описывающий обычную коробку:

у класса также определен метод Volume , возвращающий объем нашей коробки. Как определить, что один объект типа Box больше другого или равен? Условимся, что «больше» будет та коробка у которой больше объем. Теперь попробуем сделать так, чтобы платформа .NET «научилась» сравнивать коробки.

Интерфейс IComparable

Интерфейс IComparable определяет метод сравнения, который реализуется типом значения или классом для упорядочения или сортировки экземпляров и содержит всего лишь один метод — CompareTo , который должен возвращать число:

Меньше нуля Если текущий экземпляр предшествует (меньше) объекта, указанного в методе CompareTo
Нуль Если текущий экземпляр находится в том же положении (равен) объекту, указанному в методе CompareTo .
Больше нуля Если текущий экземпляр следует за объектом (больше), заданным в методе CompareTo .

Чаще всего, при реализации метода CompareTo используются числа 1 , 0 и -1 . Реализуем интерфейс IComparable в нашем классе Box :

Выше приведен подробный код реализации метода CompareTo . Но, так как результатом метода Volume является примитивный тип int , то мы можем написать наш метод намного короче, используя метод CompareTo() уже реализованный в типе Int :

Теперь мы можем сравнивать объекты типа Box , например:

Интерфейс IComparable<T>

Интерфейс IComparable имеет также обобщенную версию — IComparable<T> , используя которую мы можем немного сократить код нашего метода CompareTo следующим образом:

Как можно видеть, метод CompareTo обобщенной версии интерфейса в качестве параметра принимает объект, типа, указанного в описании, т.е. в нашем случае — типа Box , что позволяет нам избежать лишнего приведения типов.

Итого

Интерфейс IComparable предназначен для реализации в классах метода сравнения двух объектов. Этот интерфейс удобно использовать в том случае, если заранее не известно как сравнить два объекта произвольного типа. Обобщенная версия интерфейса — IComparable<T> позволяет немного упростить код метода CompareTo .

Реализация интерфейса IComparable

Если требуется отсортировать коллекцию, состоящую из объектов определяемого пользователем класса, при условии, что они не сохраняются в коллекции класса SortedList, где элементы располагаются в отсортированном порядке, то в такой коллекции должен быть известен способ сортировки содержащихся в ней объектов. С этой целью можно, в частности, реализовать интерфейс IComparable для объектов сохраняемого типа. Интерфейс IComparable доступен в двух формах: обобщенной и необобщенной. Несмотря на сходство применения обеих форм данного интерфейса, между ними имеются некоторые, хотя и небольшие, отличия.

Если требуется отсортировать объекты, хранящиеся в необобщенной коллекции, то для этой цели придется реализовать необобщенный вариант интерфейса IComparable. В этом варианте данного интерфейса определяется только один метод, CompareTo(), который определяет порядок выполнения самого сравнения. Ниже приведена общая форма объявления метода CompareTo():

В методе CompareTo() вызывающий объект сравнивается с объектом obj. Для сортировки объектов по нарастающей конкретная реализация данного метода должна возвращать нулевое значение, если значения сравниваемых объектов равны; положительное — если значение вызывающего объекта больше, чем у объекта obj; и отрицательное — если значение вызывающего объекта меньше, чем у объекта obj. А для сортировки по убывающей можно обратить результат сравнения объектов. Если же тип объекта obj не подходит для сравнения с вызывающим объектом, то в методе CompareTo() может быть сгенерировано исключение ArgumentException.

Если требуется отсортировать объекты, хранящиеся в обобщенной коллекции, то для этой цели придется реализовать обобщенный вариант интерфейса IComparable<T>. В этом варианте интерфейса IComparable определяется приведенная ниже обобщенная форма метода CompareTo():

В методе CompareTo() вызывающий объект сравнивается с другим объектом other. Для сортировки объектов по нарастающей конкретная реализация данного метода должна возвращать нулевое значение, если значения сравниваемых объектов равны; положительное — если значение вызывающего объекта больше, чем у объекта другого other; и отрицательное — если значение вызывающего объекта меньше, чем у другого объекта other. А для сортировки по убывающей можно обратить результат сравнения объектов. При реализации обобщенного интерфейса IComparable<T> имя типа реализующего класса обычно передается в качестве аргумента типа.

Давайте рассмотрим пример реализации интерфеса IComparable<T> для сортировки базы данных автомагазина:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *