C#中如何将foreach转换为Lambda/LINQ?合并分支查询逻辑
优化C#多层循环的LINQ/Lambda重构
需求说明
需要将原代码else分支的多层for/foreach循环替换为LINQ或Lambda表达式,可选择合并原if-else分支为单个查询,或保留分支结构用独立查询实现。原逻辑如下:
- 当
response.CurrentBS不为空且response.UResources是空列表时,返回CurrentBS中TaskId为0的项 - 其他场景:先筛选
CurrentBS中TaskId为0的项,再移除那些BotId(不区分大小写)与UResources中类型为Bot的Name匹配的项
方案一:合并为单个LINQ查询
通过预处理待排除的Bot名称集合,将所有逻辑整合到一个查询中,避免循环和分支判断:
// 预处理UResources中的Bot名称(转小写存入HashSet,提升查询效率) var botNamesToExclude = response.UResources?.Where(r => r.Type == ResourceType.Bot) .Select(r => r.Name.ToLower()) .ToHashSet() ?? new HashSet<string>(); var noTask = response.CurrentBS .Where(x => x.TaskId == 0) // 第一步:筛选TaskId为0的项 .Where(x => // 分支逻辑整合:若UResources为空则保留所有,否则排除匹配的BotId (response.UResources == null || response.UResources.Count == 0) || !botNamesToExclude.Contains(x.BotId.ToString().ToLower()) ) .ToList();
方案二:保留分支结构的独立查询
如果希望保留原逻辑的分支可读性,可将else分支的循环替换为LINQ查询:
List<BSS> noTask; // 预处理待排除的Bot名称集合 var botNamesToExclude = response.UResources?.Where(r => r.Type == ResourceType.Bot) .Select(r => r.Name.ToLower()) .ToHashSet() ?? new HashSet<string>(); if (response.CurrentBS.Any() && response.UResources != null && response.UResources.Count == 0) { noTask = response.CurrentBS.Where(x => x.TaskId == 0).ToList(); } else { noTask = response.CurrentBS .Where(x => x.TaskId == 0) .Where(x => !botNamesToExclude.Contains(x.BotId.ToString().ToLower())) .ToList(); }
场景验证
- 场景1(if分支触发):UResources为空列表,CurrentBS中所有项TaskId均为0,查询返回全部5个项(101、102、103、104、105),符合预期。
- 场景2(else分支触发):CurrentBS中TaskId为0的项是101、102、103;UResources中Bot类型的Name包含103,因此103被排除,最终返回101、102,符合预期。
内容的提问来源于stack exchange,提问作者AMIT SHELKE
相关产品推荐
相关产品推荐

