Должен ли IEquatable <T>, IComparable <T> быть реализован на незакрытых классах?
У любого есть мнение о том,IEquatable
или жеIComparable
как правило, требует, чтобыT
являетсяsealed
(если оно'сclass
)?
Этот вопрос возник у меня с тех пор, как яm написание набора базовых классов, предназначенных для помощи в реализации неизменяемых классов. Частью функциональности, которую должен обеспечить базовый класс, является автоматическая реализация сравнений на равенство (используя класс 's поля вместе с атрибутами, которые можно применять к полям для контроля сравнений на равенство). Это должно быть очень приятно, когда яЯ закончил - яиспользуя деревья выражений для динамического создания скомпилированной функции сравнения для каждогоT
, поэтому функция сравнения должна быть очень близка к производительности обычной функции сравнения на равенство. (Я'используя неизменный словарьSystem.Type
и дважды проверьте блокировку, чтобы сохранить сгенерированные функции сравнения таким образом, чтобыдовольно разумно)
Однако возникла одна вещь: какие функции использовать для проверки равенства полей-членов. Моим первоначальным намерением было проверить, если каждое поле участника "тип (который япозвонюX
) реализуетIEquatable
, Однако, подумав, я нене думаю, что это безопасно для использования, еслиX
являетсяsealed
, Причина в том, что еслиX
не являетсяsealed
, Я могу'не знаю наверняка, еслиX
надлежащим образом делегирует проверки на равенство виртуальному методу наX
тем самым позволяя подтипу переопределять сравнение на равенство.
Затем возникает более общий вопрос - если тип не запечатан, должен ли он действительно реализовывать эти интерфейсы ВСЕ? Я бы подумал, что нет, так как я бы сказал, что контракт интерфейсов заключается в сравнении двухX
типы, а не два типа, которые могут или не могут бытьX
(хотя они, конечно, должны бытьX
или подтип).
Что, вы парни, думаете? ДолженIEquatable
а такжеIComparable
Избегать открытых классов? (Также заставляет меня задуматься, есть ли для этого правило fxcop)
Моя текущая мысль - использовать только сгенерированную функцию сравненияIEquatable
на членских полях которыхT
являетсяsealed
и вместо того, чтобы использовать виртуальныйObject.Equals(Object obj)
еслиT
распечатывается, даже еслиT
инвентарьIEquatable
, так как поле может потенциально хранить подтипыT
и я сомневаюсь, что большинство реализацийIEquatable
разработаны соответствующим образом для наследования.