Предполагая, что мы сравниваем только объекты с одинаковыми типами времени компиляции, мы можем следовать простому двухэтапному процессу при построении выражения вызова:
- Если тип времени компиляции реализует
IEquatable<T>
, где T
- это сам тип, затем вызовите соответствующий метод Equals(T)
.
Это предотвращает упаковку в структуры, которые реализуют IEquatable<T>
, что они часто делают именно по этой причине. Он имеет дополнительное преимущество, вызывая наиболее очевидную перегрузку Equals
для классов.
В противном случае вызовите обычный (возможно переопределенный) метод
Equals(object)
.
Существует два предостережения.
Первое предостережение заключается в том, что Equals(T)
методов при отсутствии IEquatable<T>
интерфейс игнорируется. Это может считаться разумным: если разработчик не добавил интерфейс, не совсем ясно, хотели ли они, чтобы метод использовался для этой цели или нет.
Второе предостережение заключается в том, что для классов Интерфейс IEquatable<T>
в классе base игнорируется, тогда как компилятор мог бы предпочесть перегрузку, соответствующую этому. К счастью, мы можем разумно ожидать, что Equals(object)
вернет тот же результат, что и Equals(T)
для T
объекта. Если нет, разработчик предоставил неоднозначное определение равенства, и все ставки отменены.