Почему `IList <T>` не наследует от `IReadOnlyList <T>`?

Когда IReadOnlyList<T> был введен в .NET 4.5, я на мгновение подумал, что недостающая часть головоломки была наконец вставлена ​​на место: способ передать истинный индексируемый интерфейс, только когда я должен был использовать свое собственное чтение -одно интерфейсы и создавать классы-оболочки вокруг всего.

Я ожидал, что интерфейс будет помещен в "естественную" иерархию, которая в идеале была бы следующей:

IEnumerable<T> 
.GetEnumerator()
      -> IReadOnlyCollection<T> : IEnumerable<T>
      .Count
            -> IReadOnlyList<T> : IReadOnlyCollection<T>
            .Item[...]
                     -> IList<T> : IReadOnlyList<T>
                     .Add(...)
                     .Clear()
                     .Contains(...)
                     (etc)

Но, как оказалось, IList<T> не наследует от IReadOnlyList<T>.

Есть ли причина для этого?

Ответ 1

@w.b добавьте ссылку на Новые интерфейсы IReadOnlyList и IReadOnlyDictionary в комментариях, содержащих ответ:

Почему мы не изменили существующие интерфейсы для расширения интерфейсов только для чтения?

Похоже на разумное предположение, что он работает, потому что интерфейсы только для чтения являются чисто подмножеством интерфейсов чтения и записи. К сожалению, это несовместимо, потому что на уровне метаданных каждый метод на каждом интерфейсе имеет свой собственный слот (который делает работу с явным интерфейсом работы).


Immo Landwerth | Команда .NET Framework (BCL) | http://blogs.msdn.com/b/bclteam/

Чтобы объяснить это немного более четко:

Предположим, что программа, написанная для .NET 4.0, содержит класс MyList<T>, который реализует IList<T>. Он явно не может реализовать IReadOnlyList<T>, поскольку этот интерфейс не существует.

Теперь предположим, что системный администратор устанавливает .NET 4.5 и предположим, что .NET 4.5 сделал IList<T> реализовать IReadOnlyList<T>.

Если программа будет загружена, среда выполнения обнаружит, что MyList<T> заявляет о реализации IList<T>, но на самом деле не реализует все методы: она не реализует методы IReadOnlyList<T>. Программа больше не будет работать.

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