Почему List реализует IReadOnlyList in.NET 4.5?

почему List<T> реализовать IReadOnlyList<T> в .NET 4.5?

List<T> не только для чтения...

7 ответов


, потому что List<T> реализует все необходимые методы / свойства / etc. (и затем некоторые)IReadOnlyList<T>. Интерфейс-это контракт, в котором говорится: "я могу сделать по крайней мере эти вещи."

документация IReadOnlyList<T> говорит, что он представляет собой коллекцию элементов только для чтения.

Это верно. В этом интерфейсе нет методов мутатора. Это то, что означает только чтение, верно? IReadOnlyList<T> используется "типичным" (контрактным) способом, а не как маркер.


интерфейсы описывают только функциональность, которая будет реализована. Он не описывает функциональность, которая не будет реализована. IReadOnlyList - это неправильное имя интерфейса, поскольку оно не может диктовать, что функция записи не будет записана.

методы / функции описывают, что вы можете прочитать содержимое списка. Интерфейс должен был быть IReadableList вместо IReadOnlyList.


тот факт, что он реализует интерфейс, не значит, что он доступен только для чтения. Но поскольку он реализует интерфейс, теперь вы можете передать его методам, которые ожидают IReadOnlyList<T>. Таким образом, способ взглянуть на него заключается в том, что он реализует интерфейс списка только для чтения...наряду с некоторыми методами записи.


реализация интерфейса не то же самое, что" маркировка " его. List<T> осуществляет IEnumerable<T>, но это не значит, что вы ограничены простым перечислением.

они добавили интерфейсы только для чтения для создания API, а не для того, чтобы вы могли пометить свои типы только для чтения интерфейсом. Это позволяет мне использовать IReadOnlyCollection<T> для аргументов, когда я просто хочу знать количество элементов в коллекции, не перечисляя его, или IReadOnlyList<T> когда мне нужно сослаться на элементы в коллекции по индексу. Это хорошо для всех - я могу быть конкретным о том, что мне нужно от моего абонента, позволяя моему абоненту использовать любой тип коллекции, который он хочет, если он соответствует минимальному стандарту, который я установил через тип аргумента.

так что я думаю, что более сложный вопрос, почему не вы List<T> реализовать IReadOnlyList<T>?


IReadOnlyList является заменой концепции "ссылочной неизменности", найденной в C++, но не в C#. Эквивалент C++:

void func(T const* t) {...}

или точно эквивалентно, как некоторые предпочитают:

void func(const T* t) {...}

Он говорит, что функция func не мутирует объект (ы), на который ссылается его аргумент t, называемый "референтом" t. Он ничего не говорит о том, изменяет ли какой-либо другой код референт t, или даже может.

таким образом, интерфейс C# является заменой конструкции компилятора. Почему у C# нет концепции неизменности ссылок, это исторический вопрос: я думаю, что это была ошибка, но теперь уже слишком поздно ее исправлять. Я думаю, что предоставление замены интерфейса хорошо. Я использую интерфейс точно такой же, как IReadOnlyList в течение многих лет, к счастью, с другим именем IConstList. Я могу заменить использование IConstList на IReadOnlyList.


интерфейсы IReadOnlyList и IReadOnlyCollection несколько запутаны, потому что они не означают, что коллекция доступна только для чтения, просто поддерживается доступ только для чтения. От документация MSDN (прокрутите вниз до замечания)

содержимое элементов списка не гарантируется только для чтения.

лучшим именем было бы IReadable см. почему не generic ICollection реализовать IReadOnlyCollection в .NET 4.5?. Кроме того, это подразумевается, что IList должен наследовать IReadOnlyList хотя и это не из-за обратной совместимости, см. почему IList<T> наследовать от IReadOnlyList<T>?.


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