Реализация интерфейса IComparer
Для сортировки объектов определяемых пользователем классов зачастую проще всего реализовать в этих классах интерфейс IComparable. Тем не менее данную задачу можно решить и с помощью интерфейса IComparer. Для этой цели необходимо сначала создать класс, реализующий интерфейс IComparer, а затем указать объект этого класса, когда потребуется сравнение.
Интерфейс IComparer существует в двух формах: обобщенной и необобщенной. Несмотря на сходство применения обеих форм данного интерфейса, между ними имеются некоторые, хотя и небольшие, отличия.
В необобщенном интерфейсе IComparer определяется только один метод Compare():
int Compare( object x, object у) |
В методе Compare() сравниваются объекты х и у. Для сортировки объектов по нарастающей конкретная реализация данного метода должна возвращать нулевое значение, если значения сравниваемых объектов равны; положительное — если значение объекта х больше, чем у объекта у; и отрицательное — если значение объекта х меньше, чем у объекта у. А для сортировки по убывающей можно обратить результат сравнения объектов. Если же тип объекта х не подходит для сравнения с объектом у, то в методе CompareTo() может быть сгенерировано исключение ArgumentException.
Объект типа IComparer может быть указан при конструировании объекта класса SortedList, при вызове метода ArrayList.Sort(IComparer), а также в ряде других мест в классах коллекций. Главное преимущество применения интерфейса IComparer заключается в том, что сортировке подлежат объекты тех классов, в которых интерфейс IComparable не реализуется.
Интерфейс IComparer<T> является обобщенным вариантом интерфейса IComparer. В нем определяется приведенный ниже обобщенный вариант метода Compare():
int Compare(Т х, T у) |
В этом методе сравниваются объекты х и у и возвращается нулевое значение, если значения сравниваемых объектов равны; положительное — если значение объекта х больше, чем у объекта у; и отрицательное — если значение объекта х меньше, чем у объекта у.
Давайте рассмотрим пример:
using System; using System.Collections.Generic; namespace ConsoleApplication1 { class AutoShop { public string CarName { set ; get ; } public int MaxSpeed { get ; set ; } public double Cost { get ; set ; } public byte Discount { get ; set ; } public int ID { get ; set ; } public AutoShop() { } public AutoShop( string CarName, int MaxSpeed, double Cost, byte Discount, int ID) { this .CarName = CarName; this .MaxSpeed = MaxSpeed; this .Cost = Cost; this .Discount = Discount; this .ID = ID; } public override string ToString() { return String.Format( "{4}\tМарка: {0}\tМакс. скорость: {1}\tЦена: {2:C}\tСкидка: {3}%" , this .CarName, this .MaxSpeed, this .Cost, this .Discount, this .ID); } } class CompInv<T> : IComparer<T> where T : AutoShop { // Реализуем интерфейс IComparer<T> public int Compare(T x, T y) { if (x.Cost < y.Cost) return 1; if (x.Cost > y.Cost) return -1; else return 0; } } class Program { static void Main() { CompInv<AutoShop> cp = new CompInv<AutoShop>(); List<AutoShop> dic = new List<AutoShop>(); // Создадим множество автомобилей AutoShop[] autoArr = new AutoShop[5]; dic.Add( new AutoShop( "Toyota Corolla" , 180, 300000, 5, 1)); dic.Add( new AutoShop( "VAZ 2114i" , 160, 220000, 0, 2)); dic.Add( new AutoShop( "Daewoo Nexia" , 140, 260000, 5, 3)); dic.Add( new AutoShop( "Honda Torneo" , 220, 400000, 7, 4)); dic.Add( new AutoShop( "Audi R8 Best" , 360, 4200000, 3, 5)); Console.WriteLine( "Исходный каталог автомобилей: \n" ); Console.WindowWidth = 100; foreach (AutoShop a in dic) Console.WriteLine(a); Console.WriteLine( "\nТеперь автомобили отсортированны по стоимости: \n" ); dic.Sort(cp); foreach (AutoShop a in dic) Console.WriteLine(a); Console.ReadLine(); } } } |

Комментарии