请解释 C# 中 ILookup<TKey,TElement> 接口的作用,并说明通过 ToLookup 方法创建它的过程,以及在实际代码中应如何遍历和访问其中的分组数据。
考察说明
考查对 C# 集合接口 ILookup 的功能理解和实际应用能力。
回答思路
- 【回答框架 1】ILookup<TKey,TElement> 是一个只读的查找接口,继承自 IEnumerable<IGrouping<TKey,TElement>>,它将元素按键分组,并支持通过索引器或 TryGetValue 快速按键获取对应的一组元素。
- 【回答框架 2】创建时常用 Enumerable.ToLookup 扩展方法,它接受一个键选择器,可选地接受元素选择器和比较器,对序列执行一次分组操作并构建查找表,结果是一次性生成的快照。
- 【回答框架 3】使用上,可以通过 foreach 遍历 IGrouping 项,每个项包含 Key 属性和该键下的元素列表;也可以通过 lookup[key] 直接获取键对应的元素集合,若键不存在则返回空序列。
- 【回答框架 4】由于 ILookup 是不可变的,适合多次按键查询的场景;与 Dictionary 的区别在于 ILookup 的每个键可以对应多个元素,值本身是 IEnumerable 序列。
- 【回答框架 5】在 LINQ 查询中,ToLookup 常用于替代 GroupBy 后立即进行的多次按键查询,可避免重复枚举,但需要注意它在内存中完整保存分组结果。
- 【关键点 1】ILookup 是只读的多值映射,键可对应多个元素。
- 【关键点 2】使用 ToLookup 创建,支持自定义键、元素选择器和比较器。
- 【关键点 3】通过索引器访问时,缺失键返回空序列而非抛出异常。
- 【关键点 4】适合重复按键查询,但结果是一次性快照,修改源数据不会同步。
- 【易错点 1】混淆 ILookup 与 Dictionary,ILookup 一个键可对应多个元素。
- 【易错点 2】在键不存在时,索引访问返回空序列,并非抛出 KeyNotFoundException。
- 【易错点 3】将 ILookup 当作动态数据结构使用,它是只读的,不能添加或修改元素。