CA1502: Unikaj nadmiernej złożoności

Właściwości Wartość
Identyfikator reguły CA1502
Stanowisko Unikaj nadmiernej złożoności
Kategoria Łatwość konserwacji
Poprawka powodująca niezgodność lub niezgodność Niezgodność
Domyślny próg 25
Domyślnie włączone na platformie .NET 8 Nie.

Przyczyna

Metoda ma nadmierną złożoność cyklatyczną.

Opis reguły

Złożoność cyklatyczna mierzy liczbę liniowo niezależnych ścieżek przez metodę, która jest określana przez liczbę i złożoność gałęzi warunkowych. Niska złożoność cyklatyczna zwykle wskazuje metodę, która jest łatwa do zrozumienia, testowania i konserwacji. Złożoność cyklatyczna jest obliczana na podstawie wykresu przepływu sterowania metody i jest podana w następujący sposób:

złożoność cyklatyczna = liczba krawędzi — liczba węzłów + 1

Węzeł reprezentuje punkt gałęzi logiki, a krawędź reprezentuje linię między węzłami.

Reguła zgłasza naruszenie, gdy złożoność cyklatyczna metody jest większa niż 25. Można jednak skonfigurować próg , a także określić inne rodzaje symboli, które reguła powinna analizować.

Aby dowiedzieć się więcej na temat metryk kodu, zobacz Mierzenie złożoności kodu zarządzanego.

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły, refaktoryzuj metodę w celu zmniejszenia złożoności cyklatycznej.

Kiedy pomijać ostrzeżenia

Można bezpiecznie pominąć ostrzeżenie z tej reguły, jeśli nie można łatwo zmniejszyć złożoności, a metoda jest łatwa do zrozumienia, przetestowania i konserwacji. W szczególności metoda zawierająca dużą switch instrukcję (Select w Visual Basic) jest kandydatem do wykluczenia. Ryzyko destabilizacji bazy kodu pod koniec cyklu programowania lub wprowadzenia nieoczekiwanej zmiany zachowania w czasie wykonywania w wcześniej wysłanym kodzie może przewyższać korzyści z utrzymania możliwości refaktoryzacji kodu.

Uwaga

Jeśli wszystkie następujące elementy mają zastosowanie, mogą pojawić się ostrzeżenia fałszywie dodatnie z tej reguły:

  • Używasz programu Visual Studio 2022 w wersji 17.5 lub nowszej ze starszą wersją zestawu .NET SDK, czyli platformą .NET 6 lub starszą.
  • Używasz analizatorów z zestawu .NET 6 SDK lub starszej wersji pakietów analizatora, takich jak Microsoft.CodeAnalysis.FxCopAnalyzers.

Wyniki fałszywie dodatnie są spowodowane zmianą powodującą niezgodność w kompilatorze języka C#. Rozważ użycie nowszego analizatora zawierającego poprawkę dla ostrzeżeń fałszywie dodatnich. Przeprowadź uaktualnienie do wersji Microsoft.CodeAnalysis.NetAnalyzers w wersji 7.0.0-preview1.22464.1 lub nowszej lub użyj analizatorów z zestawu .NET 7 SDK.

Pomijanie ostrzeżenia

Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.

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

Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none w pliku konfiguracji.

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

Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.

Konfigurowanie progu

Można skonfigurować próg, przy którym ta reguła jest uruchamiana i jakiego rodzaju symbole mają być analizowane. Dozwolone rodzaje symboli to:

  • Assembly
  • Namespace
  • Type
  • Method
  • Field
  • Event
  • Property
  1. Utwórz plik tekstowy o nazwie CodeMetricsConfig.txt.

  2. Dodaj żądany próg do pliku tekstowego w następującym formacie:

    CA1502: 10
    

    W tym przykładzie reguła jest skonfigurowana do uruchamiania, gdy złożoność cyklatyczna metody jest większa niż 10.

    CA1502(Type): 4
    

    W tym przykładzie reguła jest skonfigurowana do uruchamiania, gdy złożoność cyklatyczna typu jest większa niż 4. W przypadku tego pliku konfiguracji reguła będzie nadal zgłaszać metody ze złożonością cyklatyczną większą niż domyślna (25).

  3. W pliku projektu oznacz akcję kompilacji pliku konfiguracji jako AdditionalFiles. Przykład:

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

Jak jest obliczana złożoność cyklatyczna

Złożoność cyklatyczna jest obliczana przez dodanie wartości 1 do następujących:

  • Liczba gałęzi (takich jak if, whilei do).
  • Liczba instrukcji case w obiekcie switch.

Przykłady

W poniższych przykładach pokazano metody, które mają różne cyklotyczne złożoności.

Złożoność cyklotyczna 1

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

Złożoność cyklotyczna 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

Złożoność cyklotyczna 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

Złożoność cyklotyczna 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: Unikaj nadmiernego dziedziczenia

Zobacz też