Почему IEquatable T не стал контравариантным в T для C # 4.0? - PullRequest
17 голосов
/ 20 июля 2010

IEquatable можно было бы объявить контравариантным в T, поскольку он использует T только во входной позиции (или, что эквивалентно, U, являющийся подтипом T, должен подразумевать, что IEquatable является [подтипом]IEquatable ).

Итак, почему команда BCL не аннотировала его (для C # 4.0) с помощью ключевого слова «in», как это было сделано со многими другими универсальными интерфейсами (например, полностью аналогичным IComparable)?

Ответы [ 2 ]

13 голосов
/ 20 июля 2010

Я думаю, что это в основном по философской причине, а не по техническим ограничениям - так как вполне возможно просто аннотировать интерфейс. IEquatable<T> предназначен для сравнения объектов одного типа на точное равенство. Экземпляр суперкласса обычно не считается равным экземпляру подкласса. Равенство в этом смысле также подразумевает равенство типов. Это немного отличается от IComparable<in T>. Может быть целесообразно определить относительный порядок сортировки для разных типов.

Цитировать Страница MSDN на IEquatable<T>:

Примечания для разработчиков:

Заменить параметр типа интерфейса IEquatable<T> на тип, реализующий этот интерфейс .

Это предложение дополнительно демонстрирует тот факт, что IEquatable<T> предназначен для работы между экземплярами одного конкретного типа.

1 голос
/ 29 мая 2012

Наследуемые типы обычно не должны реализовывать IEquatable<T>. Если IEquatable<T> включает метод GetHashCode(), можно определить семантику IEquatable<T>, чтобы сказать, что элементы должны сравниваться одинаково при рассмотрении как T. К сожалению, тот факт, что IEquatable<T> привязан к тому же хеш-коду, что и Object.Equals, означает, что в общем случае IEquatable<T> должен реализовывать по существу ту же семантику, что и Object.Equals.

Следовательно, если реализация IEquatable<BaseClass> делает что-либо кроме вызова Object.Equals внутри него, производный класс, который переопределяет Object.Equals и GetHashCode() и не повторно реализует IEquatable<BaseClass>, в результате будет поврежден реализация этого интерфейса; реализация IEquatable<BaseClass>, которая просто вызывает Object.Equals, будет отлично работать, даже в этом сценарии, но не даст реального преимущества перед классом, который не реализует IEquatable<T>.

Учитывая, что наследуемые классы не должны реализовывать IEquatable<T>, во-первых, понятие ковариации не имеет отношения к надлежащим реализациям интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...