Как упоминалось в главе 6, метод System.Object.Equals()
Equals() (часто вместе со связанным методом System.Object.GetHashCode()), то легко переопределите и операции проверки эквивалентности (== и !=). Взгляните на обновленный тип Point:// В данной версии типа Point также перегружены операции == и !=.
public class Point
{
...
public override bool Equals(object o)
=> o.ToString() == this.ToString();
public override int GetHashCode()
=> this.ToString().GetHashCode();
// Теперь перегрузить операции == и !=.
public static bool operator ==(Point p1, Point p2)
=> p1.Equals(p2);
public static bool operator !=(Point p1, Point p2)
=> !p1.Equals(p2);
}
Обратите внимание, что для выполнения всей работы в реализациях операций ==
!= просто вызывается перегруженный метод Equals(). Вот как теперь можно применять класс Point:// Использование перегруженных операций эквивалентности.
...
Console.WriteLine("ptOne == ptTwo : {0}", ptOne == ptTwo);
Console.WriteLine("ptOne != ptTwo : {0}", ptOne != ptTwo);
Console.ReadLine();
Как видите, сравнение двух объектов с использованием хорошо знакомых операций ==
!= выглядит намного интуитивно понятнее, чем вызов метода Object.Equals(). При перегрузке операций эквивалентности для определенного класса имейте в виду, что C# требует, чтобы в случае перегрузки операции == != (компилятор напомнит, если вы забудете это сделать).Перегрузка операций сравнения
В главе 8 было показано, каким образом реализовывать интерфейс IComparable
<, >, <= и >=). Как и в случае операций эквивалентности, язык C# требует, чтобы при перегрузке операции < обязательно перегружалась также операция >. Если класс Point перегружает указанные операции сравнения, тогда пользователь объекта может сравнивать объекты Point:// Использование перегруженных операций < и >.
...
Console.WriteLine("ptOne < ptTwo : {0}", ptOne < ptTwo);
Console.WriteLine("ptOne > ptTwo : {0}", ptOne > ptTwo);
Console.ReadLine();
Когда интерфейс IComparable
// Объекты Point также можно сравнивать посредством операций сравнения.
public class Point : IComparable
{
...
public int CompareTo(Point other)
{
if (this.X > other.X && this.Y > other.Y)
{
return 1;
}
if (this.X < other.X && this.Y < other.Y)
{
return -1;
}
return 0;
}
public static bool operator <(Point p1, Point p2)
=> p1.CompareTo(p2) < 0;
public static bool operator >(Point p1, Point p2)
=> p1.CompareTo(p2) > 0;
public static bool operator <=(Point p1, Point p2)
=> p1.CompareTo(p2) <= 0;
public static bool operator >=(Point p1, Point p2)
=> p1.CompareTo(p2) >= 0;
}
Финальные соображения относительно перегрузки операций
Как уже упоминалось, язык C# предоставляет возможность построения типов, которые могут уникальным образом реагировать на разнообразные встроенные хорошо известные операции. Перед добавлением поддержки такого поведения в классы вы должны удостовериться в том, что операции, которые планируется перегружать, имеют какой-нибудь смысл в реальности.