Страница 477 из 502
<b>int CompareTo(Т other)</b>
В методе CompareTo() вызывающий объект сравнивается с другим объектом other. Для сортировки объектов по нарастающей конкретная реализация данного метода должна возвращать нулевое значение, если значения сравниваемых объектов равны; положительное — если значение вызывающего объекта больше, чем у объекта другого other; и отрицательное — если значение вызывающего объекта меньше, чем у другого объекта other. А для сортировки по убывающей можно обратить результат сравнения объектов. При реализации обобщенного интерфейса IComparable<T> имя типа реализующего класса обычно передается в качестве аргумента типа.
Приведенный ниже пример программы является вариантом предыдущего примера, измененным с целью реализовать и использовать обобщенный интерфейс IComparable<T>. Обратите внимание на применение класса обобщенной коллекции List<T> вместо класса необобщенной коллекции ArrayList.
<b>// Реализовать интерфейс IComparable<T>.</b>
<b>using System;</b>
<b>using System.Collections.Generic;</b>
<b>// Реализовать обобщенный вариант интерфейса IComparable<T>.</b>
<b>class Inventory : IComparable<Inventory> {</b>
<b> string name;</b>
<b> double cost;</b>
<b> int onhand;</b>
<b> public Inventory(string n, double c, int h) {</b>
<b> name = n;</b>
<b> cost = c;</b>
<b> onhand = h;</b>
<b> }</b>
<b> public override string ToString() {</b>
<b> return</b>
<b> String.Format("{0,-10}Стоимость: {1,6:C} Наличие: {2}", name, cost, onhand);</b>
<b> }</b>
<b> // Реализовать интерфейс IComparable<T>.</b>
<b> public int CompareTo(Inventory obj) {</b>
<b> return name.CompareTo(obj.name);</b>
<b> }</b>
<b>}</b>
<b>class GenericIComparableDemo {</b>
<b> static void Main() {</b>
<b> List<Inventory> inv = new List<Inventory>();</b>
<b> // Добавить элементы в список.</b>
<b> inv.Add(new Inventory("Кусачки", 5.95, 3));</b>
<b> inv.Add(new Inventory("Отвертки", 8.29, 2));</b>
<b> inv.Add(new Inventory("Молотки", 3.50, 4));</b>
<b> inv.Add(new Inventory("Дрели", 19.88, 8));</b>
<b> Console.WriteLine("Перечень товарных запасов до сортировки:");</b>
<b> foreach (Inventory i in inv) {</b>
<b> Console.WriteLine(" " + i);</b>
<b> }</b>
<b> Console.WriteLine();</b>
<b> // Отсортировать список,</b>
<b> inv.Sort();</b>
<b> Console.WriteLine("Перечень товарных запасов после сортировки:");</b>
<b> foreach (Inventory i in inv) {</b>
<b> Console.WriteLine(" " + i);</b>
<b> }</b>
<b> }</b>
<b>}</b>
Эта версия программы дает такой же результат, как и предыдущая, необобщенная версия.
Применение интерфейса IComparer
Для сортировки объектов определяемых пользователем классов зачастую проще всего реализовать в этих классах интерфейс IComparable. Тем не менее данную задачу можно решить и с помощью интерфейса IComparer. Для этой цели необходимо сначала создать класс, реализующий интерфейс IComparer, а затем указать объект этого класса, когда потребуется сравнение.
Интерфейс IComparer существует в двух формах: обобщенной и необобщенной. Несмотря на сходство применения обеих форм данного интерфейса, между ними имеются некоторые, хотя и небольшие, отличия, рассматриваемые ниже.
В необобщенном интерфейсе IComparer определяется только один метод, Compare().
<b>int Compare(object x, object y)</b>
В методе Compare() сравниваются объекты x и у. Для сортировки объектов по нарастающей конкретная реализация данного метода должна возвращать нулевое значение, если значения сравниваемых объектов равны; положительное — если значение объекта х больше, чем у объекта у; и отрицательное — если значение объекта х меньше, чем у объекта у. А для сортировки по убывающей можно обратить результат сравнения объектов. Если же тип объекта х не подходит для сравнения с объектом у, то в методе CompareTo() может быть сгенерировано исключение ArgumentException.
Объект типа IComparer может быть указан при конструировании объекта класса SortedList, при вызове метода ArrayList.Sort(IComparer), а также в ряде других мест в классах коллекций. Главное преимущество применения интерфейса IComparer заключается в том, что сортировке подлежат объекты тех классов, в которых интерфейс IComparable не реализуется.