Sonar误判C#代码中List.Count==0为恒假,求原因解析
关于Sonar对C#代码空列表判断的误判解析
问题场景
我写了一段C#代码,逻辑是初始化List<Result>后,两次调用_sender.Send获取结果集,再通过AddRange把结果合并到列表里。之后判断列表为空时打日志并返回,但Sonar提示这个条件恒假、存在不可达代码。实际场景中两次请求都可能返回空结果,此时列表确实是空的。给AddRange加上create.Results.Any()和update.Results.Any()的判断后,警告就消失了。
初始代码(触发警告)
var results = new List<Result>(); var create = await _sender.Send<CreateResults>(createRequests, cancellationToken); results.AddRange(create.Results); var update = await _sender.Send<UpdateResults>(updateRequests, cancellationToken); results.AddRange(update.Results); if (results.Count == 0) // Sonar提示条件恒假、不可达代码 { _logger.LogInformation("No requests were generated for the given set of requets"); return; } // 后续其他网络请求逻辑
修改后代码(警告消失)
var results = new List<Result>(); var create = await _sender.Send<CreateResults>(createRequests, cancellationToken); if(create.Results.Any()) results.AddRange(create.Results); var update = await _sender.Send<UpdateResults>(updateRequests, cancellationToken); if(update.Results.Any()) results.AddRange(update.Results); if (results.Count == 0) // 无警告 { _logger.LogInformation("No requests were generated for the given set of requets"); return; } // 后续其他网络请求逻辑
误判原因
Sonar的静态分析器对List.AddRange的行为做了简化推断:它默认认为只要调用了AddRange方法,就一定会向列表中添加至少一个元素,因此会判定经过两次AddRange调用后,results.Count不可能保持初始的0值,从而误报条件恒假。
但实际场景中,create.Results或update.Results可能是空集合(Count=0),这种情况下AddRange不会对列表做任何修改,列表的Count仍然是0——这部分逻辑Sonar的静态分析没有覆盖到,导致了误判。
修改后警告消失的原因
添加create.Results.Any()和update.Results.Any()的判断后,Sonar的分析器能明确识别到:只有当结果集合中存在元素时,才会执行AddRange;如果两次结果集合都是空的,两次AddRange都会被跳过,results.Count会保持0。此时results.Count == 0的条件是可能成立的,所以警告就消失了。
内容的提问来源于stack exchange,提问作者asten_ark
相关产品推荐
相关产品推荐

