Рассмотрим этот минимальный воспроизводимый пример.
Point point1 = new Point(1, 2, 3);
Point point2 = new Point(1, 2, 31);
Console.WriteLine(point1 == point2); // True
Console.WriteLine(point1.Equals(point2)); // True
record Point(double X, double Y, double Z)
{
public virtual bool Equals(Point other)
{
return other != null && X == other.X && Y == other.Y;
}
}
Могу ли я переопределить метод == с помощью Equals? Кажется, я тоже (и не только переопределяю .Equals). Есть ли способ переопределить только один из них?
Для проверки самолетов я бы лучше сделал метод расширения public static bool IsSameXYPlane(this Point source, params Point[] others) { ... }





Для типов записей нет разницы между равенством значений (проверяется с помощью Equals) и равенством ссылок (проверяется с помощью ==). Цитируем документацию:
Те же методы и операторы, которые указывают на ссылочное равенство или неравенство в классах (например,
Object.Equals(Object)и==), указывают на равенство или неравенство значений в записях.
То есть, переопределяя метод Equals, вы также меняете поведение ==, как и ожидалось для записей.
Своеобразным частичным обходным решением было бы добавить свой собственный метод логического равенства, а не переопределять его Equals. Это позволит вам протестировать эту логику, не меняя поведение ==, но, конечно, это очень частичное решение — оно не позволит вам использовать эту логику в других классах, которые ожидают переопределения Equals (например, наборы или словари). :
// Not overriding Equals
public virtual bool LogicallyEquals(Point other)
{
return other != null && X == other.X && Y == other.Y;
}
При использовании типов записей нет разницы между равенством значений (проверено с помощью Equals) и равенством ссылок -> я не думаю, что это технически правильно. Между Equals и == нет разницы, но две записи могут иметь одинаковое «равенство значений» (те же значения полей по сравнению с EqualiytComparer<T>.Default), но разное «ссылочное равенство» (т.е. ReferenceEquals).
@IvanPetrov - реализует записи IEquatable<T>, которые EqualityComparer<T>.Default затем будут использовать, и в конечном итоге все это приведет к одному и тому же Equals методу.
@Damien_The_Unbeliever Верно, возможно, мне придется немного уточнить - я имею в виду, что Equals использует EqualityComparer<T>.Default в каждом поле для конкретного T поля.
Как вы можете видеть, оператор
==вызывает методEquals. Вы также получите ошибку компилятора, если попытаетесь указать==самостоятельно, поэтому похоже, что невозможно переопределить одно, но не другое.