public interface IComparable
Сравниваемый тип данных передается ему в качестве аргумента типа Т. В этом интерфейсе определяется метод CompareTo(), как показано ниже.
int CompareTo(Т other)
В этом методе сравниваются вызывающий объект и другой объект, определяемый параметром other. В итоге возвращается нуль, если вызывающий объект оказывается больше, чем объект other ; и отрицательное значение, если вызывающий объект оказывается меньше, чем объект other.
Для того чтобы воспользоваться методом CompareTo(), необходимо указать ограничение, которое требуется наложить на аргумент типа для реализации обобщенного интерфейса IComparable. А затем достаточно вызвать метод CompareTo(), чтобы сравнить два экземпляра параметра типа.
Ниже приведен пример применения обобщенного интерфейса IComparable. В этом примере вызывается метод InRange(), возвращающий логическое значение true, если объект оказывается среди элементов отсортированного массива.
// Требуется обобщенный интерфейс IComparable. В данном методе
// предполагается, что массив отсортирован. Он возвращает логическое
// значение true, если значение параметра what оказывается среди элементов
// массива, передаваемых параметру obs.
public static bool InRange(T what, T[] obs) where T : IComparable {
if(what.CompareTo(obs[0]) < 0 ||
what.CompareTo(obs[obs.Length-1]) > 0) return false;
return true;
}
В приведенном ниже примере программы демонстрируется применение обоих методов IsIn()и InRange()на практике.
// Продемонстрировать применение обобщенных
// интерфейсов IComparable и IEquatable.
using System;
// Теперь в классе MyClass реализуются обобщенные
// интерфейсы IComparable и IEquatable.
class MyClass : IComparable, IEquatable {
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().
public override int GetHashCode() {
return Val.GetHashCode();
}
}
class CompareDemo {
// Требуется обобщенный интерфейс IEquatable.
public static bool IsIn(T what, T[] obs)
where T : IEquatable {
foreach (T v in obs)
if (v.Equals(what)) // Применяется метод Equals()
return true;
return false;
}
// Требуется обобщенный интерфейс IComparable. В данном методе
// предполагается, что массив отсортирован. Он возвращает логическое
// значение true, если значение параметра what оказывается среди элементов
// массива, передаваемых параметру obs.
public static bool InRange(T what, T[] obs) where T : IComparable {
if (what.CompareTo(obs[0]) < 0 ||
what.CompareTo(obs[obs.Length - 1]) > 0)
return false;
return true;
}
// Продемонстрировать операции сравнения,
static void Main() {
// Применить метод Isln() к данным типа int.
int[] nums = { 1, 2, 3, 4, 5 };
if (IsIn(2, nums))
Console.WriteLine("Найдено значение 2.");
if (IsIn(99, nums))
Console.WriteLine("He подлежит выводу.");
// Применить метод Isln() к объектам класса MyClass.
MyClass[] mcs = { new MyClass(1), new MyClass(2),
new MyClass(3), new MyClass(4) };
if (IsIn(new MyClass(3), mcs))
Console.WriteLine("Найден объект MyClass(3).");
if (IsIn(new MyClass(99), mcs))
Console.WriteLine("He подлежит выводу.");
// Применить метод InRange() к данным типа int.
if (InRange(2, nums))
Console.WriteLine("Значение 2 находится в границах массива nums.");
Читать дальше