【问题标题】:Why is the SortedList(TKey,TValue).Keys property an IList(TKey) rather than a ReadOnlyCollection(TKey)?为什么 SortedList(TKey,TValue).Keys 属性是 IList(TKey) 而不是 ReadOnlyCollection(TKey)?
【发布时间】:2010-03-03 16:35:41
【问题描述】:

除了SortedList<TKey, TValue>.Keys 属性不支持的操作(例如AddRemoveInsert)之外,IList<T> 接口还包括按索引访问。

一个ReadOnlyCollection<T>,比如List<T>.AsReadOnly的返回值,实现了IList<T>,因此提供了索引访问但是通过显式实现来隐藏Add等非法操作 .此外,它只是底层列表的包装器;因此它不会创建副本,因此(我认为)不会对性能造成任何实际影响。

知道为什么SortedList<TKey, TValue.Keys 不是ReadOnlyCollection<TKey> 吗? (就此而言,为什么Values 属性不是ReadOnlyColllection<TValue>?)

【问题讨论】:

  • 奇怪的是它不是只读集合,因为如果你这样做 sortedList.Values.Add(2);它抛出异常
  • 没错!很好奇……
  • 我认为原因是 ReadOnlyCollection 是类而不是接口。使用接口你可以编写自定义存储,但 ReadOnlyCollection 有它自己的
  • 据我所知,ReadOnlyCollection<T> 类包装了实现IList<T> 的类的any 对象;所以即使Keys 属性以它自己的特殊方式实现IList<T>,它仍然可以暴露为一个简单地包装该对象的ReadOnlyCollection<T>,不管它如何实现IList<T>

标签: .net ilist sortedlist readonly-collection


【解决方案1】:

这很模糊,但我认为这是一种优化。它与泛型的实现方式有关。通用类方法的机器代码由 JIT 编译器在运行时创建。它需要制作几个具体的版本。任何参考类型都有一个。对于程序中使用的每个值类型参数,每个参数都有一个。

这可能效率低下,可能需要生成大量代码。对于通用框架类尤其不利,它们是 Ngen-ed。具体的方法实现必须是JIT编译的,不能在Ngen镜像中。

为了解决这个问题,框架中有私有代码(抱歉,我忘了在哪里),它实例化了大量各种版本的泛型类。有趣的无操作代码,让我困惑了好一阵子。但副作用是 Ngen.exe 为泛型类方法生成代码。如果您现在在自己的代码中使用这样的泛型类,您将从 Ngen 映像中获得该方法的具体实现,不需要 JIT 编译器。

您可以看到这会导致什么,System.Collections.ObjectModel.ReadOnlyCollection 可能被认为太晦涩,无法包含在此列表中。易于验证,您会发现,当您单步执行其方法时,即使您获得了参考源 .pdbs,您也不会单步执行源代码。

我不能 100% 确定这是准确的解释。但鞋子合脚。

【讨论】:

  • 非常有趣,非常有帮助的答案。我希望有这样深入的东西。现在我要自己去挖掘你在说什么。
猜你喜欢
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 2012-07-25
相关资源
最近更新 更多