В ходе реализации интерфейса IEquatable
обычно требуется также переопределять методы GetHashCode()
и Equals(Object)
, определенные в классе Object
, чтобы они оказались совместимыми с конкретной реализацией метода Equals()
. Ниже приведен пример программы, в которой демонстрируется исправленный вариант упоминавшегося ранее метода IsIn()
.
// Требуется обобщенный интерфейс IEquatable
public static bool IsIn
foreach(T v in obs)
if(v.Equals(what)) // Применяется метод Equals().
return true;
return false;
}
Обратите внимание в приведенном выше примере на применение следующега ограничения.
where Т : IEquatable
Это ограничение гарантирует, что только те типы, в которых реализован интерфейс IEquatable
, являются действительными аргументами типа для метода IsIn()
. Внутри этого метода применяется метод Equals()
, который определяет равенство одного объекта другому.
Для определения относительного порядка следования двух элементов применяется интерфейс ICompагable
. У этого интерфейса имеются две формы: обобщенная и необобщенная. Обобщенная форма данного интерфейса обладает преимуществом обеспечения типовой безопасности, и поэтому мы рассмотрим здесь именно ее. Обобщенный интерфейс IComparable
объявляется следующим образом.
public interface IComparable
Сравниваемый тип данных передается ему в качестве аргумента типа Т. В этом интерфейсе определяется метод CompareTo()
, как показано ниже.
int CompareTo(Т other)
В этом методе сравниваются вызывающий объект и другой объект, определяемый параметром
Для того чтобы воспользоваться методом CompareTo()
, необходимо указать ограничение, которое требуется наложить на аргумент типа для реализации обобщенного интерфейса IComparable
. А затем достаточно вызвать метод CompareTo()
, чтобы сравнить два экземпляра параметра типа.
Ниже приведен пример применения обобщенного интерфейса IComparable
. В этом примере вызывается метод InRange()
, возвращающий логическое значение true
, если объект оказывается среди элементов отсортированного массива.
// Требуется обобщенный интерфейс IComparable
// предполагается, что массив отсортирован. Он возвращает логическое
// значение true, если значение параметра what оказывается среди элементов
// массива, передаваемых параметру obs.
public static bool InRange
if(what.CompareTo(obs[0]) < 0 ||
what.CompareTo(obs[obs.Length-1]) > 0) return false;
return true;
}
В приведенном ниже примере программы демонстрируется применение обоих методов IsIn()
и InRange()
на практике.
// Продемонстрировать применение обобщенных
// интерфейсов IComparable
using System;
// Теперь в классе MyClass реализуются обобщенные
// интерфейсы IComparable
class MyClass : IComparable
public int Val;
public MyClass(int x) {
Val = x;
}
// Реализовать обобщенный интерфейс IComparable
public int CompareTo(MyClass other) {
return Val - other.Val; // Now, no cast is needed.
}
// Реализовать обобщенный интерфейс IEquatable
public bool Equals(MyClass other) {
return Val == other.Val;
}
// Переопределить метод Equals(Object).
public override bool Equals(Object obj) {
if (obj is MyClass)
return Equals((MyClass)obj);
return false;
}
// Переопределить метод GetHashCode().