views:

97

answers:

2

The IList<T> interface includes access by index in addition to operations not supported by the SortedList<TKey, TValue>.Keys property such as Add, Remove, and Insert.

A ReadOnlyCollection<T>, such as the return value of List<T>.AsReadOnly, implements IList<T> and therefore offers access by index but hides illegal operations like Add, etc. by implementing them explicitly. Furthermore, it is merely a wrapper for the underlying list; so it does not create a copy and should therefore (I would assume) not incur any real performance hit.

Any idea why SortedList<TKey, TValue.Keys isn't a ReadOnlyCollection<TKey>? (And for that matter why the Values property isn't a ReadOnlyColllection<TValue>?)

A: 

It is strange that it is not readonly collection, because if you do sortedList.Values.Add(2); it throws exception

Andrey
Exactly! Very curious...
Dan Tao
i think that reason is that ReadOnlyCollection is class not interface. with interface you can write custom storing, but ReadOnlyCollection has it's own
Andrey
@Andrey: As far as I know, the `ReadOnlyCollection<T>` class wraps **any** object of a class that implements `IList<T>`; so even if the `Keys` property implements `IList<T>` in its own special way, it could still be exposed as a `ReadOnlyCollection<T>` that simply wraps that object, no matter how it implements `IList<T>`.
Dan Tao
+1  A: 

This is pretty obscure, but I think this is an optimization. It has something to do with the way generics are implemented. The machine code for a generic class method is created at runtime by the JIT compiler. It needs to make several concrete versions of it. There is one for any reference type. And one each for every single value type argument that is used in a program.

That can be inefficient, potentially lots of code that needs to be generated. Especially bad for generic framework classes, they are Ngen-ed. The concrete method implementation would have to be JIT compiled and could not be in the Ngen image.

To combat that, there's private code in the framework (sorry, I forgot where), that instantiates a whole raft of various versions of generic classes. Interesting do-nothing code, it puzzled me for quite a while. But the side-effect is that Ngen.exe generates code for the generic class methods. If you now use such a generic class in your own code, you'll get the concrete implementation of the method from the Ngen image, the JIT compiler isn't needed.

You can see where that leads, System.Collections.ObjectModel.ReadOnlyCollection was probably deemed too obscure to get included in this list. Easily verifiable, you'll see that when you single step into one if its methods, you won't step into the source code, even if you got the Reference Source .pdbs.

I'm not 100% sure this is the exact explanation. But the shoe fits.

Hans Passant
Very interesting, very helpful answer. I was hoping for something in-depth like this. Now I'm going to go digging around myself for what you're talking about.
Dan Tao