KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Герберт Шилдт - C# 4.0: полное руководство

Герберт Шилдт - C# 4.0: полное руководство

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Герберт Шилдт, "C# 4.0: полное руководство" бесплатно, без регистрации.
Перейти на страницу:

class Inventory : IComparable {

  string name;

  double cost;

  int onhand;


  public Inventory(string n, double c, int h) {

    name = n;

    cost = c;

    onhand = h;

  }

  public override string ToString() { return

String.Format ("{0,-10}Стоимость: {1,6:C} Наличие: {2}", name, cost, onhand);

  }

  // Реализовать интерфейс IComparable.

  public int CompareTo(object obj) {

    Inventory b;

    b = (Inventory)obj;

    return name.CompareTo(b.name);

  }

}

class IComparableDemo {

  static void Main() {

    ArrayList inv = new ArrayList();


    inv.Add(new Inventory("Кусачки", 5.95, 3));

    inv.Add(new Inventory("Отвертки", 8.29, 2));

    inv.Add(new Inventory("Молотки", 3.50, 4));

    inv.Add(new Inventory("Дрели", 19.88, 8));


    Console.WriteLine("Перечень товарных запасов до сортировки:");

    foreach (Inventory i in inv) {

      Console.WriteLine("    " + i);

    }


    Console.WriteLine();


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

    inv.Sort();

    Console.WriteLine("Перечень товарных запасов после сортировки:");

    foreach (Inventory i in inv) {

      Console.WriteLine("    " + i);

    }

  }

}



Ниже приведен результат выполнения данной программы. Обратите внимание на то, что после вызова метода Sort() товарные запасы оказываются отсортированными по наименованию.


Перечень товарных запасов до сортировки:

    Кусачки   Стоимость:  $5,95 Наличие: 3

    Отвертки  Стоимость:  $8,29 Наличие: 2

    Молотки   Стоимость:  $3,50 Наличие: 4

    Дрели     Стоимость: $19,88 Наличие: 8

Перечень товарных запасов после сортировки:

    Дрели     Стоимость: $19,88 Наличие: 8

    Кусачки   Стоимость:  $5,95 Наличие: 3

    Молотки   Стоимость:  $3,50 Наличие: 4

    Отвертки  Стоимость:  $8,29 Наличие: 2


Реализация интерфейса IComparable для обобщенных коллекций

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


int CompareTo(Т other)


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

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


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

using System;

using System.Collections.Generic;

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

class Inventory : IComparable<Inventory> {

  string name;

  double cost;

  int onhand;

  public Inventory(string n, double c, int h) {

    name = n;

    cost = c;

    onhand = h;

  }

  public override string ToString() {

    return

  String.Format("{0,-10}Стоимость: {1,6:C} Наличие: {2}", name, cost, onhand);

  }

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

  public int CompareTo(Inventory obj) {

    return name.CompareTo(obj.name);

  }

}

class GenericIComparableDemo {

  static void Main() {

    List<Inventory> inv = new List<Inventory>();


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

    inv.Add(new Inventory("Кусачки", 5.95, 3));

    inv.Add(new Inventory("Отвертки", 8.29, 2));

    inv.Add(new Inventory("Молотки", 3.50, 4));

    inv.Add(new Inventory("Дрели", 19.88, 8));


    Console.WriteLine("Перечень товарных запасов до сортировки:");

    foreach (Inventory i in inv) {

      Console.WriteLine("    " + i);

    }


    Console.WriteLine();


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

    inv.Sort();

    Console.WriteLine("Перечень товарных запасов после сортировки:");

    foreach (Inventory i in inv) {

      Console.WriteLine("    " + i);

    }

  }

}


Эта версия программы дает такой же результат, как и предыдущая, необобщенная версия.


Применение интерфейса IComparer

Для сортировки объектов определяемых пользователем классов зачастую проще всего реализовать в этих классах интерфейс IComparable. Тем не менее данную задачу можно решить и с помощью интерфейса IComparer. Для этой цели необходимо сначала создать класс, реализующий интерфейс IComparer, а затем указать объект этого класса, когда потребуется сравнение.

Интерфейс IComparer существует в двух формах: обобщенной и необобщенной. Несмотря на сходство применения обеих форм данного интерфейса, между ними имеются некоторые, хотя и небольшие, отличия, рассматриваемые ниже.


Применение необобщенного интерфейса icomparer

В необобщенном интерфейсе IComparer определяется только один метод, Compare().


int Compare(object x, object y)


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

Объект типа IComparer может быть указан при конструировании объекта класса SortedList, при вызове метода ArrayList.Sort(IComparer), а также в ряде других мест в классах коллекций. Главное преимущество применения интерфейса IComparer заключается в том, что сортировке подлежат объекты тех классов, в которых интерфейс IComparable не реализуется.

Приведенный ниже пример программы является вариантом рассматривавшегося ранее необобщенного примера программы учета товарных запасов, переделанного с целью воспользоваться интерфейсом IComparer для сортировки перечня товарных запасов. В этом варианте программы сначала создается класс CompInv, в котором реализуется интерфейс IComparer и сравниваются два объекта класса Inventory. А затем объект класса Complnv указывается в вызове метода Sort() для сортировки перечня товарных запасов.


// Применение необобщеннкого варианта интерфейса  IComparer

using System;

using System.Collections;

// Создать объект типа IComparer для объектов класса Inventory,

class CompInv : IComparer {

  // Реализовать интерфейс IComparer.

  public int Compare(object x, object y) {

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*