C#中如何从Dictionary按指定索引项收集对应的关联值集合
字典映射关系实现修正方案
核心问题根因
- 原字典值类型定义为单个
Dot对象,无法承载“单条线段对应多个关联点”的映射存储需求 - 原字典填充逻辑会对同一个线段键重复调用
Add方法,直接触发“键已存在”的运行时异常 - 原遍历逻辑存在语法错误(
Line[i]写法无效,Line是自定义类而非可索引的数组结构)
分步修正操作
- 调整字典泛型定义
将字典值类型从单个Dot改为可动态追加元素的点集合类型List<Dot>,最终字典结构为Dictionary<Line, List<Dot>>,每个线段键对应一个存放所有关联点的列表,完全匹配业务映射需求。 - 优化字典填充逻辑
遍历点集合判断点与线段的位置关系时,先判断当前线段是否在字典中存在对应条目:- 不存在条目则先初始化空的点列表存入字典
- 存在条目则直接将符合“点在线段上”判断条件的点追加到对应列表中,从根源上避免重复添加键的异常。
- 简化遍历处理逻辑
不需要额外通过索引遍历原LinesList取值,直接遍历字典本身的键值对结构,就能拿到每一条线段、对应的全部关联点,顺次完成所有字典项的批量处理。
修正后可运行代码
public void collectingAllLines() { // 字典值改为List<Dot>,支持单个线段关联存储多个点 Dictionary<Line, List<Dot>> TempDotsInLines = new Dictionary<Line, List<Dot>>(); foreach (Line line in LinesList) { foreach (Dot dot in DotsList) { // 去掉冗余的==true判断,直接使用布尔返回值 if (line.DotIsOntheLine(dot)) { // 先判断键是否存在,避免重复添加触发异常 if (!TempDotsInLines.ContainsKey(line)) { TempDotsInLines[line] = new List<Dot>(); } // 将符合条件的点追加到当前线段的关联点列表中 TempDotsInLines[line].Add(dot); } } } // 直接遍历字典所有键值对完成处理 foreach (KeyValuePair<Line, List<Dot>> lineDotGroup in TempDotsInLines) { Line currentProcessingLine = lineDotGroup.Key; List<Dot> allRelatedDots = lineDotGroup.Value; foreach (Dot dot in allRelatedDots) { // 逐点处理逻辑写在此处 } } }
注意事项
特别提醒:如果Line类没有重写相等判断规则,Dictionary默认会通过对象引用判断键的唯一性——也就是即使两个Line对象的几何参数完全一致,只要是不同的类实例,就会被判定为不同的键存入字典。如果需要按几何参数判定同一条线段,需要给Line类实现IEquatable<Line>接口,重写Equals和GetHashCode方法。
内容的提问来源于stack exchange,提问作者user15177006
相关产品推荐
相关产品推荐

