C#中如何校验FilteredCheckObservable元素属性并修改集合对应值
业务迭代需求
- 核心迭代目标:对集合中
FilteredCheckObservable类型元素做属性校验,当满足指定条件时(例如Lang字段等于ENG),修改该元素的其他属性值(例如更新check属性为指定值),最终实现sourceGroups集合的安全同步 - 参考伪逻辑:
if (FilteredCheckObservable items.Lang == "ENG") { items.check = newcheckname; } - 核心约束:现有待优化逻辑存在集合遍历过程中直接修改集合结构的运行时异常,必须严格遵循C#集合操作规范实现,杜绝遍历枚举过程中变更集合本身的行为。
现有基础业务逻辑
以下代码为已上线的基础业务流程,主要完成生产线匹配、分组状态标记、新分组新增逻辑:
if (string.IsNullOrEmpty(departmentLine.LineID) || string.IsNullOrEmpty(departmentLine.LineName)) continue; bool discovered = false; foreach (var group in sourceGroups) { if (!group.Key.Line.IsEqual(departmentLine)) continue; group.Key.IsDiscovered = true; discovered = true; group.Key.ScheduleStatusCount = group.CountGroupItem; break; } if (discovered == false) { var _ScheduleItemObservable = new ScheduleItemObservable(departmentLine, MainViewViewModel, Shift.ToString()); var item = new Grouping<ScheduleItemObservable, FilteredCheckObservable>(_ScheduleItemObservable); if (IsShiftValid) { item.Key.Shift = Shift.ToString(); item.Key.IsHistoryEnabled = true; } sourceGroups.Add(item); }
待优化的问题代码与风险点
当前待落地的优化逻辑代码如下,存在多处不符合C#集合操作规范的问题:
for (int index = 0; index < sourceGroups.Count; index++) { if (sourceGroups[index].Key.IsDiscovered == true) { foreach (var group in sourceGroups) { foreach (FilteredCheckObservable items in group) { if (items.Lang_ID == LanguageService.Instance.LanguageType.ToString()) { sourceGroups.Clear(); sourceGroups.Add(item); } } } } }
具体风险与逻辑偏差:
- 嵌套遍历冗余:外层仅判断分组是否被标记为已发现,内层却重复遍历全量
sourceGroups集合,存在不必要的性能开销 - 运行时异常风险:在枚举遍历
group(即FilteredCheckObservable元素集合)的过程中,直接调用sourceGroups.Clear()、sourceGroups.Add()变更集合结构,会触发InvalidOperationException枚举修改异常 - 逻辑偏差:需求要求校验元素属性后修改同元素的属性值,现有代码错误实现为清空全量
sourceGroups集合后新增单个元素,完全偏离迭代目标
规范实现方案
按照C#集合操作的“分离遍历与变更”原则,根据操作场景拆分实现:
场景1:仅修改FilteredCheckObservable元素内部属性
此类操作仅变更元素自身属性,不修改sourceGroups的集合结构(无新增/删除集合元素),可直接遍历处理,无枚举异常风险:
// 遍历所有分组 foreach (var group in sourceGroups) { // 仅处理被标记为已发现的分组 if (!group.Key.IsDiscovered) continue; // 遍历分组内的FilteredCheckObservable元素 foreach (var subItem in group) { // 匹配校验条件 if (subItem.Lang_ID == LanguageService.Instance.LanguageType.ToString()) { // 仅修改元素自身属性,不涉及集合结构变更 subItem.check = newcheckname; } } }
场景2:需要变更sourceGroups集合结构(清空、新增元素)
此类操作涉及集合本身的结构修改,必须先通过遍历收集状态/待操作对象,遍历完全结束后再统一执行集合变更,禁止在枚举遍历过程中修改集合:
// 1. 遍历阶段:仅记录状态,不修改sourceGroups bool needSync = false; Grouping<ScheduleItemObservable, FilteredCheckObservable> syncItem = null; for (int i = 0; i < sourceGroups.Count; i++) { var group = sourceGroups[i]; if (!group.Key.IsDiscovered) continue; // 遍历分组内元素做校验 foreach (var subItem in group) { if (subItem.Lang_ID == LanguageService.Instance.LanguageType.ToString()) { // 记录待操作状态与对象,不直接操作集合 needSync = true; syncItem = item; // 复用基础业务流程生成的待新增分组对象 break; } } if (needSync) break; } // 2. 遍历结束后,统一执行集合变更 if (needSync && syncItem != null) { sourceGroups.Clear(); sourceGroups.Add(syncItem); }
实现注意事项
- 若需要批量操作集合元素,可先将需要操作的元素快照存入临时列表,再遍历临时列表修改目标集合,从根本上规避遍历原集合时修改集合的异常
- 嵌套遍历逻辑可根据业务规则做短路优化,匹配到目标元素后立即终止遍历,降低无意义的循环开销
内容的提问来源于stack exchange,提问作者Travis
相关产品推荐
相关产品推荐

