优先用 Any() 判断集合是否为空,尤其对 IEnumerable/IQueryable;对 List/数组等支持 Count 属性的类型,.NET 6+ 推荐用 IsEmpty;务必先判 null 再判空。

用 Any() 还是 Count == 0?先看场景再选
对已知是 List<t></t> 或数组这类支持 O(1) 计数的集合,Count == 0 和 !Any() 性能几乎没差别;但若集合是 IEnumerable<t></t>(比如 LINQ 查询结果、数据库查询返回的 IQueryable<t></t>),Any() 通常更快——它只检查第一个元素是否存在,而 Count() 会遍历全部。
常见踩坑点:把 db.Users.Where(u => u.Active).Count() == 0 当成轻量判断,实际触发全表扫描;换成 !db.Users.Where(u => u.Active).Any(),SQL 生成的是 EXISTS 子句,效率高得多。
-
Count属性(非Count()方法)只适用于实现了ICollection<t></t>的类型,如List<t></t>、Array、HashSet<t></t> -
Count()是 LINQ 扩展方法,对任意IEnumerable<t></t>都可用,但有遍历开销 -
Any()同样是扩展方法,语义清晰且短路执行,适合“是否存在”的逻辑
IsEmpty 属性在 .NET 6+ 中更安全也更直观
.NET 6 起,List<t></t>、Array、Stack<t></t>、Queue<t></t> 等都加了 IsEmpty 属性。它和 Count == 0 行为一致,但语义明确、无需括号、可读性更强,且编译器能更好优化。
注意:这个属性只存在于具体集合类型上,不适用于泛型接口如 IEnumerable<t></t> 或 ICollection<t></t> —— 想用它,得确认变量类型是具体实现类,或用 as / is 显式转换。
- ✅
list.IsEmpty(list类型是List<t></t>) - ❌
collection.IsEmpty(collection类型是ICollection<t></t>)会编译失败 - ⚠️
(collection as List<t>)?.IsEmpty ?? collection.Count == 0</t>是跨版本兼容写法,但略啰嗦
判空必须分两步:先防 null,再查空集合
直接调 list.Count == 0 或 list.Any() 前,如果 list 可能为 null,就会抛 NullReferenceException。别依赖“反正我传进来肯定不为 null”这种假设——尤其在方法参数、配置解析、API 响应反序列化后。
最简防御写法是用空传播运算符:list?.Count == 0 或 !list?.Any()。它们在 list 为 null 时整个表达式结果为 false(因为 null == 0 是 false,!null 是 true,所以后者需注意逻辑反转)。
-
list?.Count == 0→null时结果为false,表示“不为空集合”,符合直觉 -
!list?.Any()→null时结果为true,容易误判为“空”,建议改用list?.Any() == false - 更稳妥的通用模式:
list is null || list.Count == 0,逻辑清晰,无歧义
字符串和集合不能混用同一套判空逻辑
字符串用 string.IsNullOrEmpty() 或 string.IsNullOrWhiteSpace(),集合不能套用。有人写 string.IsNullOrEmpty(list?.ToString()),这是错的——list.ToString() 返回类型名,不是内容摘要。
另外,list?.Any() == false 和 list is null || !list.Any() 看似等价,但后者在调试时堆栈更清晰,前者可能掩盖 null 场景的真实意图。
真正容易被忽略的是:当集合来自外部(如 JSON 反序列化),即使字段声明为 List<t></t>,Newtonsoft.Json 默认不会自动 new 出空集合,而是设为 null —— 这时候不做 null 检查,上线后第一个请求就崩。



















