多列表可用性校验与合并返回的代码实现咨询
你的代码问题分析与优化建议
首先先把你写的代码贴出来方便讨论:
if (gardenvlist.Count() == days) { var g = gardenvlist; } if (oceanvlist.Count() == days) { var o = oceanvlist; } if (cityvlist.Count() == days) { var c = cityvlist; } var final = g.Union(o).Union(c); if (final.Count() > 0) { return new ObjectResult(final); } return NotFound();
先说说这段代码的问题
你这段代码连编译都通不过,核心问题出在变量作用域上:你在每个if代码块里声明的g、o、c,只能在对应的if块内部使用。比如如果gardenvlist.Count() != days,那g这个变量根本就没被创建,后面写g.Union(o)的时候,编译器完全不知道g是什么。
退一步说,就算你把变量声明移到if外面(比如IEnumerable<YourType> g = null;),如果某个列表不符合条件,对应的变量会是null,调用Union的时候会直接抛出空引用异常,程序崩溃。
符合你需求的正确写法
你的核心需求是:筛选出元素数量等于days的列表,合并它们,非空则返回,否则返回NotFound。我们可以换一种思路,先收集所有符合条件的列表,再合并,这样就不会有变量未定义或空引用的问题了。
写法一:分步清晰版(适合新手理解)
// 先创建一个集合,用来装所有符合条件的列表 var validLists = new List<IEnumerable<YourType>>(); // 逐个检查,符合条件就加进去 if (gardenvlist.Count() == days) { validLists.Add(gardenvlist); } if (oceanvlist.Count() == days) { validLists.Add(oceanvlist); } if (cityvlist.Count() == days) { validLists.Add(cityvlist); } // 把所有有效列表的元素合并到一起(SelectMany用来展平嵌套集合) // Distinct的作用和Union一样,用来去重,如果你的列表元素不会重复,可以去掉它 var final = validLists.SelectMany(list => list).Distinct(); // 用Any()判断是否有元素,比Count() > 0高效,因为不用遍历全部元素 if (final.Any()) { return new ObjectResult(final); } return NotFound();
写法二:简洁LINQ版(更优雅)
如果你对LINQ熟悉一点,可以用更紧凑的写法,逻辑是完全一致的:
var final = new[] { gardenvlist, oceanvlist, cityvlist } .Where(list => list.Count() == days) // 筛选符合条件的列表 .SelectMany(list => list) // 合并所有元素 .Distinct(); // 去重(可选) // 三元运算符简化判断逻辑 return final.Any() ? new ObjectResult(final) : NotFound();
额外提醒
- 如果你的三个列表本身有可能是
null(比如没初始化),那在判断Count()之前要先加list != null,改成list != null && list.Count() == days,避免空引用异常。 - 如果你不需要去重(比如三个列表的元素完全不重复),可以去掉
Distinct(),这样性能会更好一点。 - 用
Any()代替Count() > 0是个好习惯,因为Any()只要找到第一个元素就会停止遍历,而Count()必须遍历整个集合才能得到结果,数据量大的时候差异很明显。
内容的提问来源于stack exchange,提问作者supsupdb
相关产品推荐
相关产品推荐

