2010-03-03 7 views
3

Интерфейс IList<T> включает в себя доступ по индексу в дополнение к операциям, не поддерживаемым свойством SortedList<TKey, TValue>.Keys, таким как Add, Remove и Insert.Почему свойство SortedList (TKey, TValue) .Keys является IList (TKey), а не ReadOnlyCollection (TKey)?

ReadOnlyCollection<T>, например, возвращаемое значение List<T>.AsReadOnly, реализует IList<T> и, следовательно, обеспечивает доступ по индексу но скрывает незаконные операции, как Add и т.д., реализовав их явно. Кроме того, это всего лишь обертка для основного списка; поэтому он не создает копию и поэтому (я бы предположил) не подвергался реальному результату.

Любая идея, почему SortedList<TKey, TValue.Keys не является ReadOnlyCollection<TKey>? (И по этой причине, почему Values не является ReadOnlyColllection<TValue>?)

+0

Странно, что это не только сборник readonly, потому что если вы выполните сортировкуList.Values.Add (2); он выбрасывает исключение – Andrey

+0

Точно! Очень любопытно ... –

+0

Я думаю, что причина в том, что ReadOnlyCollection - это класс не интерфейс. с интерфейсом вы можете написать собственное хранение, но ReadOnlyCollection имеет свой собственный – Andrey

ответ

3

Это довольно неясно, но я думаю, что это оптимизация. Это как-то связано с тем, как генерические средства реализованы. Машинный код для метода универсального класса создается во время выполнения компилятором JIT. Он должен сделать несколько конкретных версий. Существует один для любого ссылочного типа. И по одному для каждого аргумента типа значения, который используется в программе.

Это может быть неэффективным, потенциально большим количеством кода, который необходимо сгенерировать. Особенно плохо для общих классов классов, они Ngen-ed. Реализация конкретного метода должна быть составлена ​​JIT и не может быть в изображении Ngen.

Для борьбы с этим существует частный код в рамках (извините, я забыл, где), который создает целый плот различных версий общих классов. Интересный код do-nothing, он озадачил меня довольно долгое время. Но побочным эффектом является то, что Ngen.exe генерирует код для общих методов класса. Если теперь вы используете такой общий класс в своем собственном коде, вы получите конкретную реализацию метода из изображения Ngen, компилятор JIT не понадобится.

Вы можете видеть, где это ведет, System.Collections.ObjectModel.ReadOnlyCollection, вероятно, считался слишком неясным, чтобы попасть в этот список. Легко проверяемый, вы увидите, что когда вы делаете один шаг в один, если его методы, вы не будете входить в исходный код, даже если у вас есть Reference Source .pdbs.

Я не уверен на 100%, это точное объяснение. Но обувь подходит.

+0

Очень интересный, очень полезный ответ. Я надеялся на что-то подобное. Теперь я собираюсь копаться вокруг себя за то, о чем вы говорите. –

 Смежные вопросы

  • Нет связанных вопросов^_^