Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пособие СS_Шульга.doc
Скачиваний:
48
Добавлен:
12.02.2015
Размер:
703.49 Кб
Скачать

Interface iComparable

{

Int CompareTo( object obj )

}

Метод должен возвращать:

  • 0, если текущий объект и параметр равны;

  • отрицательное число, если текущий объект меньше параметра;

  • положительное число, если текущий объект больше параметра.

Реализуем интерфейс IComparable в классе CStudent. В качестве критерия сравнения объектов выберем поле Name. В функции Mainприведена программа, сортирующая массив монстров по возрастанию ФИО.

using System;

namespace ConsoleApplication1

{

class CStudent : IComparable

{

public int CompareTo(object obj) // реализация интерфейса

{

CStudent temp = (CStudent)obj;

return String.Compare(this.name,temp.name);

}

}

class Class1

{ static void Main()

{

CStudent[] ar = {

new CStudent ("Петров", "Информатика", gender_type.male, 1),

new CStudent ("Сидоров", "Экономика", gender_type.male, 2),

new CStudent ("Уткин", "Математика", gender_type.male, 1),

new CStudent("Иванова", "Информатика", gender_type.female, 3),

new CStudent ("Антонова", "Информатика", gender_type.female, 1),

new CStudent ("Макаров", "Информатика", gender_type.male, 1)

};

Array.Sort( ar );// сортировка стала возможной

foreach ( CStudent elem in ar ) elem.output();

}

}

}

Во многих алгоритмах требуется выполнять сортировку объектов по различным критериям. В C# для этого используется интерфейс IComparer, который мы рассмотрим далее.

Сортировка по разным критериям (интерфейс IComparer)

Интерфейс IComparer определен в пространстве имен System.Collections. Он содержит один метод Compare, возвращающий результат сравнения двух объектов, переданных ему в качестве параметров:

interface IComparer

{

int Compare( object ob1, object ob2 )

}

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

Ниже приведен пример сортировки массива объектов из предыдущего примера по специальности (speciality) и году обучения (year_tr).

using System;

using System.Collections;

namespace ConsoleApplication1

{

class CStudent

{

public class SortBySpec : IComparer

{

public int Compare(object ob1, object ob2)

{

CStudent m1 = (CStudent)ob1;

CStudent m2 = (CStudent)ob2;

return String.Compare(m1.speciality, m2.speciality);

}

}

public class SortByYear : IComparer //

{

public int Compare(object ob1, object ob2)

{

CStudent m1 = (CStudent)ob1;

CStudent m2 = (CStudent)ob2;

if (m1.year_tr > m2.year_tr) return 1;

if (m1.year_tr < m2.year_tr) return -1;

return 0;

}

}

}

class Class1

{ static void Main()

{

CStudent[] ar = {

new CStudent ("Петров", "Информатика", gender_type.male, 1),

new CStudent ("Сидоров", "Экономика", gender_type.male, 2),

new CStudent ("Уткин", "Математика", gender_type.male, 1),

new CStudent("Иванова", "Информатика", gender_type.female, 3),

new CStudent ("Антонова", "Информатика", gender_type.female, 1),

new CStudent ("Макаров", "Информатика", gender_type.male, 1)

};

Console.WriteLine("Сортировка по специальности:");

Array.Sort(ar, new CStudent.SortBySpec());

foreach ( CStudent elem in ar ) elem.output();

Console.WriteLine("Сортировка по году:");

Array.Sort(ar, new CStudent.SortByYear());

foreach ( CStudent elem in ar ) elem.output();

}

}

}

Перегрузка операций отношения

Если класс реализует интерфейс IComparable, его экземпляры можно сравнивать между собой на больше-меньше. Для этого обычно перегружают операции отношения. Операции должны перегружаться парами: < и >, <= и >=, == и !=. Перегрузка операций обычно путем обращения к переопределенным методам CompareTo и Equals.

Если класс реализует интерфейс IComparable, требуется переопределить метод Equals и связанный с ним метод GetHashCode. Оба метода унаследованы от базового класса object.

Перегрузим операции отношения для класса CStudent. В качестве критерия сравнения объектов на больше-меньше выступает полеyear_tr, а при сравнении на равенство попарно сравниваются все поля объектов.

using System;

namespace ConsoleApplication1

{

class CStudent : IComparable

{

public int CompareTo(object obj)

{

CStudent temp = (CStudent)obj;

if (year_tr > temp.year_tr) return 1;

if (year_tr < temp.year_tr) return -1;

return 0;

}

public override bool Equals(object obj)

{

if (obj == null || GetType() != obj.GetType()) return false;

CStudent temp = (CStudent)obj;

return Name == temp.Name &&

speciality == temp.speciality &&

gender == temp.gender &&

year_tr == temp.year_tr;

}

public override int GetHashCode()

{

return name.GetHashCode();

}

public static bool operator ==(CStudent a, CStudent b)

{

return a.Equals(b);

}

public static bool operator !=(CStudent a, CStudent b)

{

return !a.Equals(b);

}

public static bool operator <(CStudent a, CStudent b)

{

return (a.CompareTo(b) < 0);

}

public static bool operator >(CStudent a, CStudent b)

{

return (a.CompareTo(b) > 0);

}

public static bool operator <=(CStudent a, CStudent b)

{

return (a.CompareTo(b) <= 0);

}

public static bool operator >=(CStudent a, CStudent b)

{

return (a.CompareTo(b) >= 0);

}

}

class Class1

{ static void Main()

{

CStudent s1 = new CStudent("Сидорова", "Информатика", gender_type.female, 3);

CStudent s2 = new CStudent("Иванов", "Математика", gender_type.male, 2);

if (s1 > s2) Console.WriteLine(s1.Name + " старше чем " + s2.Name);

else if (s1 < s2) Console.WriteLine(s1.Name + " младше чем " + s2.Name);

else Console.WriteLine(s1.Name+" и "+ s2.Name +" учатся на одном курсе");

if (s1 == s2) Console.WriteLine("Данные о двух студентах полностью совпадают ");

}

}

}

Результат работы программы:

Сидорова старше чем Иванов