【问题标题】:break statement issue - sonarqube中断声明问题 - sonarqube
【发布时间】:2019-09-20 05:14:40
【问题描述】:

我正在使用 sonarqube 分析我的代码并遇到以下方法的错误

public static AllocationRuleList AsAllocationRuleList(this SIGACORD.Policy acordPolicy)
    {
        foreach (var OlifeExt in acordPolicy.OLifEExtension)
        {
            var elements = new List<XmlElement>();

            foreach (var ele in OlifeExt.Any)
            {
                if (ele.Name == "AllocationRestrictions")
                {
                    var allocationRestrictionElement = acordPolicy.OLifEExtension[0]["AllocationRestrictions"];
                    return allocationRestrictionElement.AsAllocationRuleList();
                }
            }
            break;
        }
        return null;
    }

sonarqube 说我的break 应该被删除或设置为有条件的。但是,这在逻辑上不正确吗?

【问题讨论】:

  • 您开始迭代一个集合,并在第一个循环之后中断。这很奇怪,它指出它很奇怪。
  • 它只允许您运行第一次迭代,例如,您可以使用 System.Linq 命名空间中的var OlifeExt = acordPolicy.OLifEExtension.First()

标签: c# foreach sonarqube


【解决方案1】:

您的代码是有效的 c# 代码,但声纳与编译器无关。 Sonar 会验证您的代码是否没有令人困惑的结构,而这个结构令人困惑。您不想迭代您只想要第一项的集合。所以你的代码应该表达你的意图。所以你应该这样做

var OlifeExt = acordPolicy.OLifEExtension.FirstOrDefault();
if(OlifeExt  != null)
// ...

【讨论】:

    【解决方案2】:

    您的break 将导致循环在第一项之后退出。这违背了循环的目的。

    和这个是一样的:

        // a for loop does nothing if there are no items in the collection
        if(acordPolicy.OLifEExtension).Any()
        {
    
            // no loop - we just take the first item.
            var OlifeExt = acordPolicy.First(); 
            var elements = new List<XmlElement>();
    
            foreach (var ele in OlifeExt.Any)
            {
                if (ele.Name == "AllocationRestrictions")
                {
                    var allocationRestrictionElement = acordPolicy.OLifEExtension[0]["AllocationRestrictions"];
                    return allocationRestrictionElement.AsAllocationRuleList();
                }
            }
        }
        return null;
    

    如果您真的只想查看集合中的第一项,那么您编写的代码 - 第一次迭代后带有 breakfor 循环 - 将起作用。但这令人困惑。有人必须通读全文才能意识到for 循环在第一项之后退出。然后他们会怀疑你是否打算这样做。然后他们会阅读更多内容,试图弄清楚发生了什么。

    如果您只想查看集合中的第一项,那么最好明确地执行此操作。

    【讨论】:

      【解决方案3】:

      如果break;不是基于某些条件,那么在任何循环中都没有意义,例如:

      foreach (var OlifeExt in acordPolicy.OLifEExtension)
      {
        if(OlifeExt == something)
        { 
          break;
        }
      
        // else continue looping and do your thing
      }
      

      【讨论】:

        【解决方案4】:

        “break”表示跳出当前循环(外部foreach)。如果您要查找的值不是集合中的第一个值,那么您将始终返回 null。

        假设这不是你的想法,这样的事情应该会更好:

        public static AllocationRuleList AsAllocationRuleList(this SIGACORD.Policy acordPolicy)
            {
                foreach (var OlifeExt in acordPolicy.OLifEExtension)
                {
                    var restrictions = OlifeExt.FirstOrDefault(f => f.Name == "AllocationRestrictions");
                    if (restrictions == null) continue;
        
                    return restrictions.AsAllocationRuleList();
                }
                return null;
            }
        

        【讨论】:

          猜你喜欢
          • 2015-08-28
          • 1970-01-01
          • 2021-08-03
          • 2021-04-21
          • 2011-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多