为什么.net中没有OrderedDictionary的通用实现?


26

Microsoft为什么不提供OrderedDictionary的通用实现?

我见过一些自定义实现,包括:http : //www.codeproject.com/KB/recipes/GenericOrderedDictionary.aspx

但是,为什么Microsoft不将其包含在基本.net库中?当然,他们有理由不构建泛型。...但这是什么?

在发布此消息之前,我确实看到了:https : //stackoverflow.com/questions/2629027/no-generic-implementation-of-ordereddictionary

但这只是证实它不存在。不是为什么它不存在。

谢谢


2
总有SortedDictionary<TKey, TValue>msdn.microsoft.com/en-us/library/f7fta44c.aspx
Travis Gockel,2010年

2
除非我误解了SortedDict文档,否则这不是我想要的。我不想做任何排序。我只想要一个我也可以通过键访问的数组。无论如何,我真的很奇怪为什么MS跳过了这一步。(细微的问题等)
nonot1 2010年

有序词典的典型用例是什么?我努力地想着一个问题。
Carson63000

1
@Carson随时随地都有需要快速随机访问的数据项数组。仅存储在Dict中会丢失订购信息,而使用数组则需要您维护自己的索引。
nonot1 2010年

2
请埃里克·利珀特(Eric Lippert)阅读并回答您的问题。他通常非常乐于帮助解决此类问题。我想您可以通过他的博客与他联系:blogs.msdn.com/b/ericlippert
devuxer 2011年

Answers:


17

C#4.0中,我读到以下内容:

  1. An OrderedDictionary是a HashTableArrayList
  2. 没有通用的 ArrayList
  3. “非泛型ArrayList类主要用于与Framework 1.x向后兼容...”
  4. “在ArrayList功能上类似于List<object>
  5. “使用非泛型ArrayList比使用反射更容易List<object>

结论?

没有泛型,OrderedDictionary因为它的基础构造是一个(非官方的)折旧的类,本身没有泛型版本。


4
这并不能真正回答问题。一个通用的OrderedDictionary显然可以建立在一个通用的Dictionary和一个通用的List上。
JacquesB

类使用的一个戒律是,如果UI不变,那么谁在乎实现呢?好吧,假设语言设计/编译器团队更喜欢泛型继承其非泛型对应。我的间谍感令人吃惊。对于初学者:不同的(立即)祖先是否在协方差和对立方差的进化路径中的某个地方存在 OrderedDictionary
radarbob

15

OrderedDictionary重载索引操作,使索引与整数N将获得位置的项目N,而与索引Object将检索coresponding到该对象的项目。如果要创建一个OrderedDictionary<int, string>被调用的myDict,并以该顺序添加项目(1,“ George”)和(0,“ Fred”),应该myDict[0]返回“ George”还是“ Fred”?

通过在键类型上施加类约束,可以解决此问题。另一方面,通用集合的许多有用性都来自它们有效使用值类型的能力。在键类型上施加类约束似乎有些丑陋。

如果该类不必与CLS兼容,而仅需与vb.net一起使用,则可能已使用了明智的设计来使用命名索引属性。因此,在上面的示例中,myDict.ByKey[0]将产生“ Fred”,并且myDict.BySequence[0]将产生“ George”。不幸的是,诸如C#之类的语言不支持命名索引属性。尽管即使没有这样的属性,也可能已经想出了一些允许使用上述语法的东西,但不幸的是,决定包装像PointRectangle这样的结构的字段,这意味着myDict.ByKey[0] = "Wally"要工作,myDict.ByKey必须返回一个新的类对象。结构会更有效,但是编译器会拒绝看起来像对只读结构的写操作(尽管该属性不会修改由...返回的结构ByKey,而是修改它保存引用的集合)。

就我个人而言,我认为指定为跟踪插入顺序的字典式对象将是一件好事。我还希望有一个字典式的对象,该对象可以轻松返回与特定键相关联的键(这样,例如,如果一个人具有不区分大小写的字典,并添加了一个键为“ GEORGE”的记录,可以问字典与“ George”关联的键是什么,而不必搜索KeyValuePair枚举中返回的所有对象。


3

因为维护顺序会阻止IDictionary隐含的O(1)查找,除非您包装了两个集合(一个用于顺序,一个用于查找),这会使添加/删除性能降低并增加了内存使用量。或者,您可能会发现查找速度较慢,以减少内存使用量。

我的猜测是,这里没有“明显更好”的选择,因此它没有进入标准库。尤其是在2.0左右,C#仍在学习Java的错误。如果Java的标准库中的“一切和厨房水槽”方法也被视为可以避免的事情,我不会感到惊讶。


1
查找速度变慢以换取较少的内存只会使OrderedDictionarya 有效List。我以为任何一个拥有合理用例的人OrderedDictionary都在专门使用它,因为他们需要一个具有O(1)查找但还记得插入顺序的集合类,在这种情况下,不可避免地要使用额外的内存,因此是可以接受的。
Abion47年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.