除了 SortedList.Keys
属性(例如 AddIList
接口还包括按索引进行访问>、删除
和插入
。
ReadOnlyCollection
(例如 List.AsReadOnly
的返回值)实现 IList
,因此提供以下访问:索引但通过显式实现来隐藏诸如添加
等非法操作。此外,它只是底层列表的包装器;因此它不会创建副本,因此(我认为)不会造成任何实际的性能影响。
知道为什么 SortedList 不是 ReadOnlyCollection
吗? (就此而言,为什么 Values
属性不是 ReadOnlyCollection
?)
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>
?)
发布评论
评论(1)
这相当晦涩,但我认为这是一种优化。它与泛型的实现方式有关。泛型类方法的机器代码是由 JIT 编译器在运行时创建的。它需要制作几个具体版本。任何参考类型都有一个。程序中使用的每个值类型参数各有一个。
这可能效率低下,可能需要生成大量代码。对于通用框架类来说尤其糟糕,它们是 Ngen 化的。具体方法实现必须进行 JIT 编译,并且不能位于 Ngen 映像中。
为了解决这个问题,框架中有私有代码(抱歉,我忘了在哪里),它实例化了大量各种版本的泛型类。有趣的无所事事的代码,它让我困惑了很长一段时间。但副作用是 Ngen.exe 为泛型类方法生成代码。如果您现在在自己的代码中使用这样的泛型类,您将从 Ngen 映像中获得该方法的具体实现,不需要 JIT 编译器。
您可以看到这会导致什么结果,System.Collections.ObjectModel.ReadOnlyCollection 可能被认为太晦涩而无法包含在此列表中。易于验证,您会发现,当您单步执行其方法时,即使您获得了参考源 .pdbs,您也不会单步执行源代码。
我不能 100% 确定这是准确的解释。但鞋子很合脚。
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.