using System;

using System.Collections;

namespace ComparableCar

{

  public class Car

  {

    ...

    public int CarID {get; set;}

    public Car(string name, int currSp, int id)

    {

      CurrentSpeed = currSp;

      PetName = name;

      CarID = id;

    }

    ...

  }

}

Теперь предположим, что имеется следующий массив объектов Car:

using System;

using ComparableCar;

Console.WriteLine("***** Fun with Object Sorting *****\n");

// Создать массив объектов Car.

Car[] myAutos = new Car[5];

myAutos[0] = new Car("Rusty", 80, 1);

myAutos[1] = new Car("Mary", 40, 234);

myAutos[2] = new Car("Viper", 40, 34);

myAutos[3] = new Car("Mel", 40, 4);

myAutos[4] = new Car("Chucky", 40, 5);

Console.ReadLine();

В классе System.Array определен статический метод по имени Sort(). Его вызов для массива внутренних типов (int, short, string и т.д.) приводит к сортировке элементов массива в числовом или алфавитном порядке, т.к. внутренние типы данных реализуют интерфейс IComparable. Но что произойдет, если передать методу Sort() массив объектов Car?

// Сортируются ли объекты Car? Пока еще нет!

Array.Sort(myAutos);

Запустив тестовый код, вы получите исключение времени выполнения, потому что класс Car не поддерживает необходимый интерфейс. При построении специальных типов вы можете реализовать интерфейс IComparable, чтобы позволить массивам, содержащим элементы этих типов, подвергаться сортировке. Когда вы реализуете детали СоmраrеТо(), то должны самостоятельно принять решение о том, что должно браться за основу в операции упорядочивания. Для типа Car вполне логичным кандидатом может служить внутреннее свойство CarID:

// Итерация по объектам Car может быть упорядочена на основе CarID.

public class Car : IComparable

{

  ...

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

  int IComparable.CompareTo(object obj)

  {

    if (obj is Car temp)

    {

      if (this.CarID > temp.CarID)

      {

        return 1;

      }

      if (this.CarID < temp.CarID)

      {

        return -1;

      }

      return 0;

    }

    throw new ArgumentException("Parameter is not a Car!");

                           // Параметр не является объектом типа Car!

  }

}

Как видите, логика метода CompareTo() заключается в сравнении входного объекта с текущим экземпляром на основе специфичного элемента данных. Возвращаемое значение метода CompareTo() применяется для выяснения того, является текущий объект меньше, больше или равным объекту, с которым он сравнивается (табл. 8.1).

Предыдущую реализацию метода CompareTo() можно усовершенствовать с учетом того факта, что тип данных int в C# (который представляет собой просто сокращенное обозначение для типа System.Int32) реализует интерфейс IComparable. Реализовать CompareTo() в Car можно было бы так:

int IComparable.CompareTo(object obj)

{

  if (obj is Car temp)

  {

    return this.CarID.CompareTo(temp.CarID);

  }

  throw new ArgumentException("Parameter is not a Car!");

                            // Параметр не является объектом типа Car!

}

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

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

// Создать массив объектов Car.

...

// Отобразить текущее содержимое массива.

Console.WriteLine("Here is the unordered set of cars:");

foreach(Car c in myAutos)

{

  Console.WriteLine("{0} {1}", c.CarID, c.PetName);

}

// Теперь отсортировать массив с применением IComparable!

Array.Sort(myAutos);

Console.WriteLine();

// Отобразить отсортированное содержимое массива.

Перейти на страницу:

Похожие книги