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

Вид: 19672|Ответ: 1

[Источник] . .NET История интерфейса коллекции только для чтения

[Скопировать ссылку]
Опубликовано 05.02.2018 14:28:10 | | |
.NET 4.5Добавлены два новых интерфейса коллекций — IReadOnlyList и IReadOnlyDictionary. Хотя на первый взгляд эти интерфейсы могут показаться обыденными, они раскрывают довольно сложные истории о обратной совместимости, совместимости и роли комутируемости.

IReadOnlyList и IReadOnlyDictionary — это два интерфейса, которые разработчики .NET всегда хотели иметь. Помимо обеспечения некоторой симметрии (в отличие от записываемых интерфейсов), интерфейс только для чтения должен исключать реализацию методов, которые только выдают исключение NotSupportedException и ничего не делают. Всё это не было завершено из-за нехватки времени.

Следующая возможность появилась. NET 2.0. Это позволяет Microsoft вывести из эксплуатации слабо типированные коллекции и заменить их на сильно типизированные коллегии. Однако команда базовой библиотеки[1] вновь упустила возможность предоставить список только для чтения, как писал Кит Джордж,

Поскольку мы намерены предоставить стандартную реализацию для вашей задачи с Джо, вместо предоставления интерфейса, мы предоставляем базовый класс ReadOnlyCollectionBase. Однако я понимаю, почему люди неохотно используют его, ведь это не сильный тип. Но с появлением дженериков у нас теперь есть <T>ReadOnlyCollection, так что вы получаете не только ту же функциональность, но и сильный шрифт: отлично!

Поскольку ReadOnlyCollection <T>не является запечатанным классом, при необходимости вы можете писать собственную коллекцию на полной скорости. Поскольку эти коллекции, которые мы создали для этого, адаптируются к общим потребностям, мы не планируем вводить интерфейсы для этой же концепции.

Кшиштоф Цвалина также выразил своё мнение по этой теме,

Звучит это удивительно или нет, IList <T>и IList — это два интерфейса, которые мы планируем использовать для коллекций только для чтения. Оба имеют булевое свойство IsReadOnly, которое должно возвращать true, когда это свойство реализует только для чтения. Причина, по которой мы не хотим добавлять полностью доступный только для чтения, в том, что он добавляет слишком много ненужной сложности в базовую библиотеку. Обратите внимание, что с точки зрения сложности мы имеем в виду как этот новый интерфейс, так и его пользователей.

Мы считаем, что если дизайнер API не заботится о проверке свойства IsReadOnly во время выполнения и возможных исключений, то в этом случае можно использовать интерфейс IList; Если они готовы предоставить действительно чистый пользовательский API за один раз, то в данном случае им стоит показать реализацию интерфейса IList и опубликовать индивидуальный API, предназначенный только для чтения. Последнее типично для коллекций, открытых из объектной модели.

Хотя разработчики жаловались на эту ситуацию, новые возможности, предоставляемые дженериками, значительно перевешивают эту суть, и проблема заключается в . Ранее NET 4 в основном игнорировали. Однако это решение вызвало и некоторые реакции, о которых мы поговорим позже.

С выходом. В процесс выполнения добавлена захватывающая новая функция в .NET 4. В более ранней версии. .NET, когда интерфейсы становятся типами, эти интерфейсы слишком ограничены. Например, даже если Customer наследует от Person, невозможно передать объект типа <Customer>IEnumerable в качестве параметра функции типа IEnumerable<Person>. С добавлением ковариантной поддержки это ограничение было частично снято.

Мы говорим «частично», потому что в некоторых случаях людям стоит сразу использовать интерфейс с насыщенным API, а не использовать интерфейс IEnumerable. Даже если интерфейс IList не ковариантен, интерфейс списка только для чтения должен быть ковариантным. К сожалению, . Команда базовой библиотеки .NET снова решила не решать этот упучок.

Затем появление WinRT и возвращение COM изменили всё. Совместимость COM когда-то была технологией, которую разработчики использовали, когда у них не было другого выбора, но теперь она стала . Краеугольный камень программирования .NET. И поскольку WinRT открывает <T>интерфейсы IVectorView и IMapView<K, V> соответственно. .NET также необходимо корректировать соответствующим образом.

Интересной особенностью программы WinRT является анонс о появлении разных, но похожих API для каждой платформы разработки. Как вы, возможно, уже знаете, все имена методов представлены camelCased [2], тогда как разработчики C++ и .NET рассматривают имена методов как PascalCased [3]. Ещё одним более радикальным изменением стало автоматическое сопоставление между интерфейсами C++ и .NET. Следовательно. Разработчикам .NET не нужно иметь дело с пространством имён Windows.Foundation.Collections, они просто продолжают использовать пространство имён System.Collections.Generic. <T>Интерфейсы IVectorView и IMapView<K, V> будут преобразованы в интерфейсы IReadOnlyList <T>и IReadOnlyDictionary<TKey, TValue> соответственно.

Стоит отметить, что эти имена интерфейсов в C++/WinRT в определённой степени более точны. Эти интерфейсы используются для представления некоторых представлений коллекции, но интерфейс не гарантирует неизменность самой коллекции. Даже среди опытных. Распространённая ошибка среди разработчиков .NET — предполагать, что тип ReadOnlyCollection — это копия неизменяемой коллекции, но на самом деле это просто обёртка для активной коллекции (см. пост Эндрю Арнотта с тем же названием для получения дополнительной информации о коллекциях только для чтения, замороженных и неизменяемых).

Хотя <T>интерфейс IList имеет все те же элементы, что и интерфейс IReadOnlyList<T>, и все списки типа IList <T>могут быть представлены как списки только для чтения, IList <T>не наследует от IReadOnlyList<T>, что может быть интересно для изучения. Иммо Ландверт объяснил,

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

Другими словами, единственный шанс ввести интерфейс только для чтения как базовый класс переменного класса — это вернуться к . NET 2.0, то есть когда они были изначально задуманы. После полного внедрения единственное изменение — добавление ковариантных и/или инверторных маркеров (обозначаемых как «вход» и «выход» в VB и C#).

На вопрос, почему нет <T>интерфейса IReadOnlyCollection, Иммо ответил:

Мы рассматривали этот дизайн, но считали, что добавление типа, который предоставляет только атрибут Count, не добавит большой ценности базовой библиотеке. В команде базовой библиотеки мы считаем, что если API начинается с минус 1000, то даже добавление какой-то ценности недостаточно, чтобы оправдать его добавление. Обоснование добавления новых API также включает стоимость, например, у разработчиков будет больше концепций на выбор. Сначала мы думали, что добавление такого типа поможет коду работать лучше в определённых ситуациях, когда нужно получить счёт и сделать что-то интересное. Например, массовое добавление в существующую коллекцию. Однако в таких случаях мы поощряем людей использовать только <T>интерфейс IEnumerable, а в <T>особом случае наличие экземпляра, реализующего интерфейс ICollection. С тех пор как все наши встроенные типы коллекций реализовали этот интерфейс, в этих наиболее распространённых ситуациях не было прироста производительности. Кстати, <T>метод расширения Count() для IEnumerable тоже может это сделать.

Эти новые интерфейсы доступны для . NET 4.5 и . NET for Windows 8。

Примечания к переводу

[1] Библиотека базового класса, сокращённо BCL. Для получения дополнительной информации о библиотеке базового класса, пожалуйста, участвуйте в MSDN.

[2] верблюжий корпус, номенклатура горба, также известная как нижний верблюжий корпус. Формат таков: первое слово начинается с строчной буквы; Первая буква второго слова пишется с заглавной буквы, например: firstName, lastName.

[3] PascalCased, номенклатура Pascal, также известная как верхний верблюжий корпус. Формат таков: первая буква каждого слова пишется с заглавной буквы, например: FirstName, LastName, CamelCase.




Предыдущий:Платформа лицензирования программного обеспечения .NET/C# [Исходный код]
Следующий:JS Mining — как Monero майнить с помощью веб-майнинга?
Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com