Должен ли IEquatable <T>, IComparable <T> быть реализован на незакрытых классах?

У любого есть мнение о том,IEquatable<T> или жеIComparable<T> как правило, требует, чтобыT являетсяsealed (если этоclass)?

Этот вопрос возник у меня, так как я пишу набор базовых классов, предназначенных для помощи в реализации неизменяемых классов. Частью функциональности, которую должен обеспечить базовый класс, является автоматическая реализация сравнений на равенство (используя поля класса вместе с атрибутами, которые можно применять к полям для управления сравнениями на равенство). Это должно быть очень приятно, когда я закончу - я использую деревья выражений для динамического создания скомпилированной функции сравнения для каждогоT, поэтому функция сравнения должна быть очень близка к производительности обычной функции сравнения на равенство. (Я использую неизменный словарьSystem.Type и двойная проверка блокировки, чтобы сохранить сгенерированные функции сравнения способом, который является достаточно эффективным)

Однако возникла одна вещь: какие функции использовать для проверки равенства полей-членов. Моим первоначальным намерением было проверить, является ли тип каждого члена поля (который я назовуX) реализуетIEquatable<X>, Однако, после некоторых размышлений, я не думаю, что это безопасно использовать, еслиX являетсяsealed, Причина в том, что еслиX не являетсяsealedЯ не могу знать наверняка, еслиX надлежащим образом делегирует проверки на равенство виртуальному методу наXтем самым позволяя подтипу переопределять сравнение на равенство.

Затем возникает более общий вопрос - если тип не запечатан, должен ли он действительно реализовывать эти интерфейсы ВСЕ? Я бы подумал, что нет, так как я бы сказал, что контракт интерфейсов заключается в сравнении двухX типы, а не два типа, которые могут или не могут бытьX (хотя они, конечно, должны бытьX или подтип).

Что вы ребята думаете? ДолженIEquatable<T> а такжеIComparable<T> Избегать открытых классов? (Также заставляет меня задуматься, есть ли для этого правило fxcop)

Моя текущая мысль - использовать только сгенерированную функцию сравненияIEquatable<T> на членских полях, чьиT являетсяsealedи вместо того, чтобы использовать виртуальныйObject.Equals(Object obj) еслиT распечатывается, даже еслиT инвентарьIEquatable<T>, так как поле может потенциально хранить подтипыT и я сомневаюсь, что большинство реализацийIEquatable<T> разработаны соответствующим образом для наследования.

Ответы на вопрос(4)

Ваш ответ на вопрос