为什么IDictionary<TKey,TValue>不能实现ILookup<TKey,TValue>?

3

我想这并不重要,只是出于好奇。

如果字典和查找的区别在于一个是一对一关系,另一个是一对多关系,那么字典不是更具体/派生版本的查找吗?

查找是一组键/值对的集合,其中键可以重复使用。 字典是一组键/值对的集合,其中键不能重复使用。

为什么IDictionary不能实现ILookup?

3个回答

4
我怀疑这主要是因为意图不同。 ILookup<T,U> 的设计专为处理值的集合。而 IDictionary<T,U> 则旨在处理单个值(当然,该值也可以是一个集合)。
虽然你当然可以通过返回一个带有单个值的 IEnumerable<U> 实现对 IDictionary<T,U> 进行操作,但这会让人困惑,特别是如果你的“U”本身就是一个集合(例如: List<int>)。在这种情况下,ILookup<T,U>.Item 应该返回一个 IEnumerable<List<int>> 吗?还是应该检查一个 IEnumerable<T> 值类型,然后“展平”它?无论哪种方式,都会变得混乱,并增加可疑的价值。

不仅仅是“意图”不同。字典是每个键一个值。ILookup是一个或多个键的值。此外,ILookup只能由LINQ查询创建,并且是不可变的;您不能稍后添加更多的键或值。(至少在3.5版本中是这样的,不知道4.0版本是否也是如此。) - Cylon Cat
@Cylon:ILookup是一个接口 - 如果您愿意,可以实现自己的不可变版本。正如我所提到的,您可以强制Dictionary<T,U>实现ILookup<T,U>,但如果这样做会令人困惑。 - Reed Copsey

2

接口IDictionary<T,U>ILookup<T,U>都继承了IEnumerable。如果将IDictionary<T,U>强制转换为IEnumerable,并在其上调用GetEnumerator(),则生成的枚举器应返回KeyValuePair<T,U>的实例。如果将ILookup<T,U>强制转换为IEnumerable,并在其上调用GetEnumerator(),则生成的枚举器应返回IGrouping<T,U>的实例。如果KeyValuePair<T,U>结构被修改以实现IGrouping<T,U>,那么这可能是可行的,但不够干净。


1

我猜这是因为 IDictionary'2 接口比 ILookup'2 早出现很久了。回头修改是不必要的。具体实现可以使用 ILookup'2。我不认为修改一个人们已经使用多年的接口会有什么好处。


我认为你也可以反过来表述。我不明白修改接口会有什么损害。是的,ILookup 是较新的,但这并不意味着它不能描述 IDictionary 的功能。仅仅因为你和我看不到可能获得的好处,并不意味着它对某个人没有帮助,只是我们个人无法看到如何帮助。 - Josh
1
如果人们修改了现有的流行界面的行为,会发生什么?哦,为什么不会有任何伤害出现…… - surfasb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接