Я анализирую свой код с помощью 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 должен быть удален или сделан условным. но разве это не логически правильно?

1
testing 1 Май 2019 в 19:46

4 ответа

Лучший ответ

Ваш код является допустимым кодом C #, но сонар не о том, что компилятор. Сонар проверяет, если ваш код не имеет сбивающих с толку конструкций, а эта сбивает с толку. Вы не хотите повторять коллекцию, вы хотите только первый элемент. Таким образом, ваш код должен выражать ваше намерение этого. Так что вы должны сделать

var OlifeExt = acordPolicy.OLifEExtension.FirstOrDefault();
if(OlifeExt  != null)
// ...
1
Rafal 1 Май 2019 в 16:51

Ваш 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;

Если вы действительно хотите посмотреть на первый элемент в коллекции, тогда написанный вами код - цикл for с break после первой итерации - сработает. Но это сбивает с толку. Кто-то должен будет прочитать все это, чтобы понять, что цикл for завершается после первого элемента. Тогда они будут удивляться, если вы хотели это сделать. Затем они прочитают еще немного, пытаясь выяснить, что происходит.

Если вы просто хотите посмотреть на первый элемент в коллекции, лучше сделать это явно.

1
Scott Hannen 1 Май 2019 в 21:06

«обрыв» означает выход из токовой петли (внешний foreach). Если искомое значение не является первым в коллекции, то вы всегда будете возвращать ноль.

Предполагая, что это не то, что вы имели в виду, что-то вроде этого должно работать лучше:

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;
    }
0
Steve Todd 1 Май 2019 в 16:59

Нет смысла иметь break; в любом цикле, если он не основан на каком-либо условии, например:

foreach (var OlifeExt in acordPolicy.OLifEExtension)
{
  if(OlifeExt == something)
  { 
    break;
  }

  // else continue looping and do your thing
}
0
Milenko Jevremovic 1 Май 2019 в 16:51