Почему IComparable <T>не наследуется от IComparable? - PullRequest
3 голосов
/ 23 сентября 2019

В большинстве мест я читал, что в ваших классах рекомендуется наследовать от IComparable и IComparable<T> для обеспечения совместимости с неуниверсальными коллекциями.У меня вопрос, почему IComparable<T> не наследуется от IComparable по умолчанию?Обратная совместимость будет достигнута таким образом.

Например, IEnumerable<T> наследуется от IEnumerable, так почему бы не сделать то же самое с IComparable?Я читал о вариациях, но до сих пор не понимаю, почему это было разработано именно так.Я попытался создать небольшой пример с интерфейсами с той же архитектурой, и он работает как задумано.

Редактировать: Кроме того, документация Microsoft гласит следующее: Универсальные интерфейсы могут наследоваться от неуниверсальных интерфейсов, если универсальный интерфейсКонтравариант, что означает, что он использует только свой тип параметра в качестве возвращаемого значения.В библиотеке классов .NET Framework IEnumerable<T> наследуется от IEnumerable, поскольку IEnumerable<T> использует T только в возвращаемом значении GetEnumerator и в получателе свойства Current.

Но, несмотря на это,можно просто унаследовать IComparable от IComparable<T> (если вы создаете интерфейсы с такими же архитектурами).

Ответы [ 2 ]

0 голосов
/ 23 сентября 2019

Это сводится к решению Language Design, поэтому, если не считать слова разработчиков, мы можем только догадываться.

Одна веская причина, безусловно, в том, что один является общим, а другой - нет.Обобщения по своей природе превосходят неуниверсальное решение (которое означает использование объекта в качестве типа), поскольку они поддерживают безопасность типов во время компиляции.Так что, возможно, был преднамеренный выбор порвать с предродовой версией.Чтобы избежать нисходящей совместимости.Обратите внимание, что большинство классов, которые реализуют Generic Version, не реализуют его неуниверсальный аналог.Действительно фундаментальные и старые вещи, такие как string, являются исключением - потому что они не могут удалить старый интерфейс, только добавить новые.

С нумераторами потребность кажется менее экстремальной.Перечислители, как правило, генерируются взамен или из коллекции и предназначены исключительно для чтения.Таким образом, у вас либо есть фиксированный тип для приведения, либо фиксированный тип для использования в Enumerator.

Другая причина, вероятно, состоит в том, что код, использующий IComparable, либо явно его требует (ограничения типа), либо состоит из элементов, сделанных из него.- и сам по себе является общим по определению.Чаще всего он используется для функций сортировки в общих коллекциях.Возможно, они больше не хотели использовать старые коллекции.А не поддержка IComparable для Dictionary, безусловно, был хорошим выбором, чтобы вывести HashTable (его предварительный аналог) из обращения.

0 голосов
/ 23 сентября 2019

Попробуйте сами, если тип не указан, тогда классу, реализующему универсальный интерфейс, также потребуется реализовать метод типа по умолчанию

    public interface IFoo
    {
        void Foo(object o);
    }

    public interface IFoo<T> : IFoo
    {
        void Foo(T o);
    }

, который превращается в

public class Foo : IFoo<int>
    {
        void IFoo<int>.Foo(int o)
        {
            throw new System.NotImplementedException();
        }

        void IFoo.Foo(object o)
        {
            throw new System.NotImplementedException();
        }
    }

В этом случае выреализовать один интерфейс с одним методом, и кажется, что вы должны реализовать два метода, если вы наследуете от типизированного интерфейса

...