ILookup接口与IDictionary的区别

90

6
“Multi-map”支持是首先想到的事情(一个键可以映射到一组值)。 - user166390
可能是"Lookup<TKey,TElement>有什么用?"的重复问题。 - Uwe Keim
3个回答

129

ILookup条目可以包含多个与每个键相关联的项,每个键都映射到一个IEnumerable<TElement>

正如评论中所暗示的那样,ILookup是不可变的,而您可以在IDictionary中更新值(它公开了一个Add()方法和一个索引器,允许获取并且设置值)。

总之,它们的用例非常不同-当您需要具有固定且不会(也无法)更改的值的1:N映射时,请使用查找。另一方面,字典提供了可变的1:1键值对映射,因此可以通过添加或删除值来更新它。


1
实际上,每个条目都是 IEnumerable<T> 而不是 T - Gabe
1
+1 虽然如此,如果能更详细地了解接口差异、更新可变性、关键要求等方面的内容会更好。 - user166390
实现 ILookup<TElement> 并不能保证不可变性。你的回答似乎暗示了这一点。它仅仅提供了一个可读的 视图 。此外,接受 ILookup<TElement> 参数的方法如何处理查找内容的更改取决于该方法——如果没有文档说明,最好在外部代码仍然引用并依赖于您的用例时避免更改查找。请参见完整讨论,了解人们错误地认为实现 IReadOnlyList<T> 应该意味着列表是不可变的。 - binki
1
@binki 如果你计划对 ILookup<TKey, TElement> 的可变实现进行修改,那是一个不好的主意。如果没有文档,你应该能够假设它遵循其接口。当然,现实生活总是复杂的,但如果你使用其中一个 ToLookup 扩展方法创建了一个查找表,可以安全地假设它不会被修改。虽然有一些方法可以修改它,但你的 ILookup<TKey, TElement> 类型成员的使用者应该遵循最小惊讶原则。如果你发现传递给你的对象以可观察的方式进行了修改,就要 throw 异常。 - Aluan Haddad
1
我的评论有语法错误:我的意思是你的消费者应该能够假定你遵循了最少惊讶原则。 - Aluan Haddad
是的。修改传递给接受只读视图的方法的对象是一个坏主意,如IReadOnlyDictionaryILookup。我只是试图区分“只读视图”和“不可变”。我还想指出,由于IDictionary<TKey, TValue>.IsReadOnly存在,IDictionary并不一定是可变的。抱歉过于吹毛求疵xD。 - binki

4

它比 IDictionary 简单得多。它被 Linq 使用。它只有 ContainsItemCount。而 IDictionary 则有 AddRemove 等方法。


你的意思是ILookup是IDictionary的只读子集吗? - Timothy Swan
1
有点类似,但每个元素都是IGrouping,因此一个键可以有多个元素,所以它不太适合映射。如果Dictionary有一个只读接口就好了。 - Philippe
2
@Philippe 字典的只读接口是IReadOnlyDictionary<TKey, TValue>,并且所有 Dictionary<TKey, TValue> 类的实例都可以实现它(ToDictionary 返回类实例,因此也可以使用),因此您可以将任何字典公开为只读。 - Los Frijoles
1
@LosFrijoles 谢谢,我不知道这个存在。我目前被困在 .NET 4.0 中,并错误地假设它不存在,没有在 MSDN 上检查。 - Philippe

2

ILookUp => 按键分组,可枚举集合

单个键值是指可枚举集合,我们可以遍历值集合。

IDictionary => 按唯一键分组,单个值


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