Добавить в цитаты Настройки чтения

Страница 477 из 502

<b>int CompareTo(Т other)</b>

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

Приведенный ниже пример программы является вариантом предыдущего примера, измененным с целью реализовать и использовать обобщенный интерфейс IComparable&lt;T&gt;. Обратите внимание на применение класса обобщенной коллекции List&lt;T&gt; вместо класса необобщенной коллекции ArrayList.

<b>// Реализовать интерфейс IComparable&lt;T&gt;.</b>

<b>using System;</b>

<b>using System.Collections.Generic;</b>

<b>// Реализовать обобщенный вариант интерфейса IComparable&lt;T&gt;.</b>

<b>class Inventory : IComparable&lt;Inventory&gt; {</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(&quot;{0,-10}Стоимость: {1,6:C} Наличие: {2}&quot;, name, cost, onhand);</b>

<b>  }</b>

<b>  // Реализовать интерфейс IComparable&lt;T&gt;.</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&lt;Inventory&gt; inv = new List&lt;Inventory&gt;();</b>

<b>    // Добавить элементы в список.</b>

<b>    inv.Add(new Inventory(&quot;Кусачки&quot;, 5.95, 3));</b>

<b>    inv.Add(new Inventory(&quot;Отвертки&quot;, 8.29, 2));</b>

<b>    inv.Add(new Inventory(&quot;Молотки&quot;, 3.50, 4));</b>

<b>    inv.Add(new Inventory(&quot;Дрели&quot;, 19.88, 8));</b>

<b>    Console.WriteLine(&quot;Перечень товарных запасов до сортировки:&quot;);</b>

<b>    foreach (Inventory i in inv) {</b>

<b>      Console.WriteLine(&quot;    &quot; + i);</b>

<b>    }</b>

<b>    Console.WriteLine();</b>

<b>    // Отсортировать список,</b>

<b>    inv.Sort();</b>

<b>    Console.WriteLine(&quot;Перечень товарных запасов после сортировки:&quot;);</b>

<b>    foreach (Inventory i in inv) {</b>

<b>      Console.WriteLine(&quot;    &quot; + 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 не реализуется.