Как статический словарь имеет цикломатическую сложность?

У меня есть следующий класс:

public static class MyClass
{
    private static readonly Dictionary<Type, Func<string, object>> valueTypes;

    static MyClass()
    {
        var dictionary = new Dictionary<Type, Func<string, object>>();
        dictionary.Add(typeof(bool), x => bool.Parse(x));
        dictionary.Add(typeof(byte), x => byte.Parse(x));
        dictionary.Add(typeof(char), x => char.Parse(x));
        dictionary.Add(typeof(decimal), x => decimal.Parse(x));
        dictionary.Add(typeof(double), x => double.Parse(x));
        dictionary.Add(typeof(float), x => float.Parse(x));
        dictionary.Add(typeof(int), x => int.Parse(x));
        dictionary.Add(typeof(long), x => long.Parse(x));
        dictionary.Add(typeof(sbyte), x => sbyte.Parse(x));
        dictionary.Add(typeof(short), x => short.Parse(x));
        dictionary.Add(typeof(uint), x => uint.Parse(x));
        dictionary.Add(typeof(ulong), x => ulong.Parse(x));
        dictionary.Add(typeof(ushort), x => ushort.Parse(x));
        MyClass.valueTypes = dictionary;
    }
}

Однако Microsoft Code Analysis помечает это как наличие цикломатической сложности 27. Я не понимаю, почему серия вызовов Add с делегатами приводит к такой высокой цикломатической сложности.

Что я могу сделать, чтобы уменьшить цикломатическую сложность?


person cubetwo1729    schedule 22.10.2012    source источник
comment
См. stackoverflow.com/questions/10244131/   -  person cm007    schedule 22.10.2012
comment
Лямбда-выражения похожи на айсберг. Синтаксический сахар очень сладок, но этот код создает 13 вложенных классов и 26 условных переходов в коде конструктора. Единственный способ увидеть это — посмотреть на это так, как это делает инструмент анализа, запустив ildasm.exe на сборке.   -  person Hans Passant    schedule 22.10.2012


Ответы (1)


Мне нравится это определение для CC — the amount of decision logic in a source code function (см. подробнее на «Метрики кода — цикломатическая сложность", также есть очень хороший пример того, как рассчитывается CC).

Итак, поскольку у каждого Add() есть два разных пути кода — сам Add() и функция Value, поэтому CC+=2. Так как вы поставили Add() 13 раз - CC == минимум 26. А в отношении MSDN минимальный CC равен 2, и когда он увеличивается, он начинает увеличиваться с 1, поэтому вы получаете 27 :) Наличие анонимного метода в значении словаря увеличивает сложность, поскольку потенциально он может вызвать исключение, поэтому его следует охватить тестом также.

Значения метрик кода, MSDN:

Цикломатическая сложность — измеряет структурную сложность кода. Он создается путем подсчета количества различных путей кода в потоке программы. Программа со сложным потоком управления потребует больше тестов для достижения хорошего покрытия кода и будет менее ремонтопригодной.


Просто интересно проверить, что такое CC для этих примеров:

private static readonly Dictionary<Type, Func<string, object>> valueTypes
static MyClass()     
{         
    var dictionary = new Dictionary<Type, Func<string, object>>();         
    dictionary.Add(typeof(bool), x => bool.Parse(x)); 
}


static MyClass()     
{         
    var dictionary = new Dictionary<Type, Func<string, object>>();         
    Func<string, object> func = (x) => bool.Parse(x)
    dictionary.Add(typeof(bool), func); 
}

static MyClass()     
{         
    var dictionary = new Dictionary<Type, Func<string, object>>();         
    dictionary.Add(typeof(bool), null); 
}
person sll    schedule 22.10.2012