Ранее мы рассмотрели корректную реализацию минимально необходимого набора доработок класса для сравнения объектов класса по значению.
Теперь рассмотрим Type-specific реализацию сравнения объектов по значению, включающую реализацию Generic-интерфейса IEquatable(Of T) и перегрузку операторов "==" и "!=".
Type-specific сравнение объектов по значению позволяет достичь:
- Более стабильного, масштабируемого и мнемонического (читаемого) кода (последнее за счет перегруженных операторов).
- Более высокой производительности.
Кроме того, реализация Type-specific сравнения по значению необходима по причинам:
- Стандартные Generic-коллекции (List(Ot T), Dictionary(Of TKey, TValue) и др.) рекомендуют наличие реализации IEquatable(Of T) для всех объектов, помещаемых в коллекции.
- Стандартный компаратор EqualityComparer(Of T).Default использует (по умолчанию — при наличии) реализацию IEquatable(Of T) у операндов.
Реализация одновременно всех способов сравнения сопряжена определенными с трудностями, т.к. для корректной работы требуется обеспечить:
- Соответствие результатов сравнения у различных способов.
- Сохранение поведения при наследовании.
- Минимизацию copy-paste и общего объема кода.
- Учет того, что операторы сравнения технически являются статическими методами и, соответственно, у них отсутствует полиморфность (а также, что не все CLS-совместимые языки поддерживают операторы или их перегрузку).
Рассмотрим реализацию сравнения объектов по значению с учетом вышеизложенных условий, на примере класса Person.
Сразу приведем окончательный вариант кода с пояснениями, почему это сделано именно так, и как именно это работает.
(Демонстрация вывода решения с учетом каждого нюанса содержит слишком много итераций.)
Читать полностью »