CA1502: Vyhněte se nadměrné složitosti

Vlastnost Hodnota
ID pravidla CA1502
Název Vyhněte se nadměrné složitosti
Kategorie Udržovatelnost
Oprava způsobující chybu nebo chybu způsobující chybu Nenarušující
Výchozí prahová hodnota 25
Povoleno ve výchozím nastavení v .NET 8 No

Příčina

Metoda má nadměrnou cyklomatickou složitost.

Popis pravidla

Cyklomatická složitost měří počet lineárních nezávislých cest metodou, která je určena počtem a složitostí podmíněných větví. Nízká cyklomatická složitost obecně označuje metodu, která je snadno pochopitelná, testovat a udržovat. Cyklomatické složitosti se vypočítá z grafu toku řízení metody a je uveden takto:

cyklomaticová složitost = počet hran - počet uzlů + 1

Uzel představuje bod větve logiky a hrana představuje čáru mezi uzly.

Pravidlo hlásí porušení, pokud cyklomaticická složitost metody je větší než 25. Můžete ale nakonfigurovat prahovou hodnotu a také zadat další druhy symbolů, které má pravidlo analyzovat.

Další informace o metrikách kódu najdete v tématu Měření složitosti spravovaného kódu.

Jak opravit porušení

Chcete-li opravit porušení tohoto pravidla, refaktorujte metodu, aby se snížila jeho cyklomatická složitost.

Kdy potlačit upozornění

Je bezpečné potlačit upozornění z tohoto pravidla, pokud složitost nelze snadno snížit a metoda je snadno pochopitelná, testovat a udržovat. Konkrétně je metoda, která obsahuje velký switch příkaz (Select v jazyce Visual Basic) je kandidátem na vyloučení. Riziko aktivace základu kódu v pozdní fázi vývojového cyklu nebo zavedení neočekávané změny chování za běhu v dříve dodaném kódu může převažovat nad výhodami udržovatelnosti refaktoringu kódu.

Poznámka:

Falešně pozitivní upozornění z tohoto pravidla se můžou zobrazit, pokud platí všechny tyto skutečnosti:

  • Používáte Sadu Visual Studio 2022 verze 17.5 nebo novější se starší verzí sady .NET SDK, tj. .NET 6 nebo starší.
  • Používáte analyzátory ze sady .NET 6 SDK nebo starší verze balíčků analyzátoru, například Microsoft.CodeAnalysis.FxCopAnalyzers.

Falešně pozitivní výsledky jsou způsobeny zásadní změnou kompilátoru jazyka C#. Zvažte použití novějšího analyzátoru, který obsahuje opravu falešně pozitivních upozornění. Upgradujte na Microsoft.CodeAnalysis.NetAnalyzers verze 7.0.0-preview1.22464.1 nebo novější nebo použijte analyzátory ze sady .NET 7 SDK.

Potlačení upozornění

Pokud chcete pouze potlačit jedno porušení, přidejte do zdrojového souboru direktivy preprocesoru, abyste pravidlo zakázali a znovu povolili.

#pragma warning disable CA1502
// The code that's violating the rule is on this line.
#pragma warning restore CA1502

Pokud chcete pravidlo pro soubor, složku nebo projekt zakázat, nastavte jeho závažnost v none konfiguračním souboru.

[*.{cs,vb}]
dotnet_diagnostic.CA1502.severity = none

Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.

Konfigurace prahové hodnoty

Můžete nakonfigurovat prahovou hodnotu, při které se toto pravidlo aktivuje, a druhy symbolů, které se mají analyzovat. Povolené druhy symbolů jsou:

  • Assembly
  • Namespace
  • Type
  • Method
  • Field
  • Event
  • Property
  1. Vytvořte textový soubor s názvem CodeMetricsConfig.txt.

  2. Do textového souboru přidejte požadovanou prahovou hodnotu v následujícím formátu:

    CA1502: 10
    

    V tomto příkladu je pravidlo nakonfigurované tak, aby se aktivovalo, když je složitost cyklomatické metody větší než 10.

    CA1502(Type): 4
    

    V tomto příkladu je pravidlo nakonfigurované tak, aby se aktivovalo, když je složitost cyklomatického typu větší než 4. V tomto konfiguračním souboru by pravidlo pokračovalo v hlášení metod s cyklomatickou složitostí větší než výchozí (25).

  3. V souboru projektu označte akci sestavení konfiguračního souboru jako AdditionalFiles. Příklad:

    <ItemGroup>
      <AdditionalFiles Include="CodeMetricsConfig.txt" />
    </ItemGroup>
    

Výpočet cyklomatické složitosti

Cyklomatické složitosti se vypočítá přidáním hodnoty 1 k následujícímu:

  • Počet větví (například if, whilea do).
  • Počet case příkazů v parametru switch.

Příklady

Následující příklady ukazují metody, které mají různé cyklomaticické složitosti.

Cyklomaticová složitost 1

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

Cyklomatická složitost 2

void Method(bool condition)
{
    if (condition)
    {
        Console.WriteLine("Hello World!");
    }
}
Public Sub Method(ByVal condition As Boolean)
    If (condition) Then
        Console.WriteLine("Hello World!")
    End If
End Sub

Cyklomatická složitost 3

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

Cyklomatická složitost 8

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;
    }
}
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

CA1501: Vyhněte se nadměrné dědičnosti

Viz také