如何优化包含空值检查的代码?附待优化代码片段
优化多层空值检查代码的几种思路
嘿,我来帮你搞定这段嵌套空值检查代码的优化!这段代码里层层叠叠的null判断确实有点冗余,咱们可以借助C#的语法特性和编程技巧,让它变得更简洁、易读还不容易出错。
先看看你的原代码:
if (objA != null && objA.Length > 0) { foreach (var child in objA ) { if (child.Any != null) { foreach (var a in child.Any) { if (a.Name.ToLower() == "code") { //some code } } } } }
方法一:使用空条件运算符(?.)简化空值检查
C# 6及以上版本支持的?.运算符可以帮我们避免手动写大量null判断,它会在对象为null时直接返回null,而不是抛出异常。结合??空合并运算符(提供默认值),我们可以把嵌套逻辑扁平化:
// 先处理objA为null或空的情况,直接跳过 if (objA == null || objA.Length == 0) return; foreach (var child in objA) { // 用?.判断child.Any是否为null,为null时直接跳过循环 foreach (var a in child.Any ?? Enumerable.Empty<YourAType>()) { // 这里还要注意a或a.Name可能为null,所以加上?. if (a?.Name?.ToLower() == "code") { // some code } } }
方法二:用LINQ链式查询彻底消除嵌套
如果你的场景允许,用LINQ的链式调用可以把整个循环逻辑转换成声明式的查询,代码会更紧凑,逻辑也更清晰:
// 从objA开始,层层过滤非null项,最后找到符合条件的a var targetItems = objA?.Where(child => child.Any != null) .SelectMany(child => child.Any) // 把所有child.Any合并成一个序列 .Where(a => a?.Name?.ToLower() == "code") ?? Enumerable.Empty<YourAType>(); foreach (var a in targetItems) { // some code }
这里的SelectMany可以把嵌套的集合“展平”,避免嵌套循环;?? Enumerable.Empty<YourAType>()则是为了防止objA为null时出现空引用异常。
方法三:封装逻辑到单独方法(提升可读性)
如果这段查询逻辑会被多次用到,或者你想让主代码更干净,可以把过滤逻辑封装成一个单独的方法:
private IEnumerable<YourAType> GetCodeItems(YourObjAType[] objA) { if (objA == null) yield break; foreach (var child in objA) { if (child.Any == null) continue; foreach (var a in child.Any) { if (a?.Name?.ToLower() == "code") yield return a; } } } // 主代码里直接调用 foreach (var a in GetCodeItems(objA)) { // some code }
这种方式把复杂的过滤逻辑隐藏在方法里,主代码只需要关注“拿到符合条件的项并处理”,可读性大大提升。
额外提醒
别忘了处理a.Name为null的情况!原代码里如果a或a.Name是null,调用ToLower()会抛出空引用异常,所以用a?.Name?.ToLower()可以安全处理这种情况。
内容的提问来源于stack exchange,提问作者Jasmine
相关产品推荐
相关产品推荐

