Поделиться через


CA1502: избегайте чрезмерной сложности

TypeName

AvoidExcessiveComplexity

CheckId

CA1502

Категория

Microsoft.Maintainability

Критическое изменение

Не критическое

Причина

Метод отличается чрезмерной цикломатической сложностью.

Описание правила

Цикломатическая сложность измеряет количество линейно независимых путей в методе, которое определяется числом и сложностью условных ветвей. Низкой цикломатической сложностью, как правило, отличаются методы, которые просты для понимания, проверки и поддержки. Цикломатическая сложность вычисляется на основе диаграммы потока управления метода в соответствии со следующим выражением:

цикломатическая сложность = количество граней - количество узлов + 1

где узел представляет логическую точку ветвления, а грань — линию между узлами.

Предупреждение о нарушении правила выводится в том случае, если цикломатическая сложность превышает значение 25.

Устранение нарушений

Чтобы устранить нарушение данного правила, измените структуру метода, чтобы снизить цикломатическую сложность.

Отключение предупреждений

Отключение предупреждений данного правила безопасно в том случае, если сложность метода трудно уменьшить, а сам метод прост для понимания, проверки и поддержки. В частности, метод, содержащий объемный оператор switch (Select в Visual Basic), является первым кандидатом на исключение из этого правила. Риск дестабилизации базового кода позднее в процессе цикла разработки или внесения непредвиденных изменений в поведение времени выполнения ранее поставленного кода может перевесить преимущества удобства поддержки, возникающие при оптимизации кода.

Процедура вычисления цикломатической сложности

Цикломатическая сложность вычисляется посредством добавления единицы к следующим значениям:

  • Число ветвей (таких как операторы if, while и do)

  • Число операторов case в блоке switch

В следующих примерах показаны методы с различной цикломатической сложностью.

Пример

Цикломатическая сложность 1

Public Sub Method()
    Console.WriteLine("Hello World!")
End Sub
public void Method()
{
    Console.WriteLine("Hello World!");
}
void Method()
{
    Console::WriteLine("Hello World!");
}

Цикломатическая сложность 2

Public Sub Method(ByVal condition As Boolean)
    If (condition) Then
        Console.WriteLine("Hello World!")
    End If
End Sub


void Method(bool condition)
{
    if (condition)
    {
        Console.WriteLine("Hello World!");
    }
}
void Method(bool condition)
{ 
  if (condition)
    { 
        Console::WriteLine("Hello World!"); 
    } 
}

Цикломатическая сложность 3


Public Sub Method(ByVal condition1 As Boolean, ByVal condition2 As Boolean)
    If (condition1 OrElse condition2) Then
        Console.WriteLine("Hello World!")
    End If
End Sub
public void Method(bool condition1, bool condition2)
{
    if (condition1 || condition2)
    {
        Console.WriteLine("Hello World!");
    }
}
void Method(bool condition1, bool condition2)
{
    if (condition1 || condition2)
    {
        Console::WriteLine("Hello World!");
    }
}

Цикломатическая сложность 8


    Public Sub Method(ByVal day As DayOfWeek)
        Select Case day
            Case DayOfWeek.Monday
                Console.WriteLine("Today is Monday!")
            Case DayOfWeek.Tuesday
                Console.WriteLine("Today is Tuesday!")
            Case DayOfWeek.Wednesday
                Console.WriteLine("Today is Wednesday!")
            Case DayOfWeek.Thursday
                Console.WriteLine("Today is Thursday!")
            Case DayOfWeek.Friday
                Console.WriteLine("Today is Friday!")
            Case DayOfWeek.Saturday
                Console.WriteLine("Today is Saturday!")
            Case DayOfWeek.Sunday
                Console.WriteLine("Today is Sunday!")
        End Select
    End Sub

    public void Method(DayOfWeek day)
    {

        switch (day)
        {
            case DayOfWeek.Monday:
                Console.WriteLine("Today is Monday!");
                break;
            case DayOfWeek.Tuesday:
                Console.WriteLine("Today is Tuesday!");
                break;
            case DayOfWeek.Wednesday:
                Console.WriteLine("Today is Wednesday!");
                break;
            case DayOfWeek.Thursday:
                Console.WriteLine("Today is Thursday!");
                break;
            case DayOfWeek.Friday:
                Console.WriteLine("Today is Friday!");
                break;
            case DayOfWeek.Saturday:
                Console.WriteLine("Today is Saturday!");
                break;
            case DayOfWeek.Sunday:
                Console.WriteLine("Today is Sunday!");
                break;
        }
    }

}
void Method(DayOfWeek day)
{
    switch (day)
    {
        case DayOfWeek::Monday:
            Console::WriteLine("Today is Monday!");
            break;
        case DayOfWeek::Tuesday:
            Console::WriteLine("Today is Tuesday!");
        break;
        case DayOfWeek::Wednesday:
            Console::WriteLine("Today is Wednesday!");
        break;
        case DayOfWeek::Thursday:
            Console::WriteLine("Today is Thursday!");
        break;
        case DayOfWeek::Friday:
            Console::WriteLine("Today is Friday!");
        break;
        case DayOfWeek::Saturday:
            Console::WriteLine("Today is Saturday!");
        break;
        case DayOfWeek::Sunday:
            Console::WriteLine("Today is Sunday!");
        break;
    }
}

Связанные правила

CA1501: избегайте излишнего наследования