Dela via


CA1502: Undvik överdriven komplexitet

Property Värde
Regel-ID CA1502
Title Undvik överdriven komplexitet
Kategori Underhåll
Korrigeringen är icke-bakåtkompatibel Icke-icke-bryta
Standardtröskelvärde 25
Aktiverad som standard i .NET 9 Nej

Orsak

En metod har en överdriven cyklomatisk komplexitet.

Regelbeskrivning

Cyklomatisk komplexitet mäter antalet linjärt oberoende sökvägar genom metoden, vilket bestäms av antalet och komplexiteten hos villkorsgrenar. En låg cyklomatisk komplexitet indikerar vanligtvis en metod som är lätt att förstå, testa och underhålla. Den cyklomatiska komplexiteten beräknas från ett kontrollflödesdiagram för metoden och ges på följande sätt:

cyklomatisk komplexitet = antalet kanter – antalet noder + 1

En nod representerar en logikgrenpunkt och en kant representerar en linje mellan noder.

Regeln rapporterar en överträdelse när den cyklomatiska komplexiteten för en metod är mer än 25. Du kan dock konfigurera tröskelvärdet och även ange andra typer av symboler som regeln ska analysera.

Du kan lära dig mer om kodmått i Mäta komplexitet för hanterad kod.

Så här åtgärdar du överträdelser

Om du vill åtgärda ett brott mot den här regeln omstrukturerar du metoden för att minska dess cyklomatiska komplexitet.

När du ska ignorera varningar

Det är säkert att ignorera en varning från den här regeln om komplexiteten inte enkelt kan minskas och metoden är lätt att förstå, testa och underhålla. I synnerhet är en metod som innehåller en stor switch (Select i Visual Basic) -instruktion en kandidat för exkludering. Risken för att destabilisera kodbasen sent i utvecklingscykeln eller införa en oväntad ändring i körningsbeteendet i tidigare levererad kod kan uppväga underhållsfördelarna med att omstrukturera koden.

Kommentar

Du kan se falska positiva varningar från den här regeln om alla följande gäller:

  • Du använder Visual Studio 2022 version 17.5 eller senare med en äldre version av .NET SDK, dvs. .NET 6 eller tidigare.
  • Du använder analysverktygen från .NET 6 SDK eller en äldre version av analyspaketen, till exempel Microsoft.CodeAnalysis.FxCopAnalyzers.

Falska positiva identifieringar beror på en icke-bakåtkompatibel ändring i C#-kompilatorn. Överväg att använda en nyare analysator som innehåller korrigeringen för falska positiva varningar. Uppgradera till Microsoft.CodeAnalysis.NetAnalyzers version 7.0.0-preview1.22464.1 eller senare eller använd analysverktygen från .NET 7 SDK.

Ignorera en varning

Om du bara vill förhindra en enda överträdelse lägger du till förprocessordirektiv i källfilen för att inaktivera och aktiverar sedan regeln igen.

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

Om du vill inaktivera regeln för en fil, mapp eller ett projekt anger du dess allvarlighetsgrad till none i konfigurationsfilen.

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

Mer information finns i Så här utelämnar du kodanalysvarningar.

Konfigurera tröskelvärde

Du kan konfigurera tröskelvärdet där den här regeln utlöses och vilka typer av symboler som ska analyseras. De tillåtna symboltyperna är:

  • Assembly
  • Namespace
  • Type
  • Method
  • Field
  • Event
  • Property
  1. Skapa en textfil med namnet CodeMetricsConfig.txt.

  2. Lägg till det önskade tröskelvärdet i textfilen i följande format:

    CA1502: 10
    

    I det här exemplet konfigureras regeln att utlösas när en metods cyklomatiska komplexitet är större än 10.

    CA1502(Type): 4
    

    I det här exemplet konfigureras regeln att utlösas när en typs cyklomatiska komplexitet är större än 4. Med den här konfigurationsfilen skulle regeln fortsätta att rapportera metoder med en cyklomatisk komplexitet som är större än standardvärdet (25).

  3. Markera konfigurationsfilens byggåtgärd som AdditionalFiles i projektfilen. Till exempel:

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

Hur cyklomatisk komplexitet beräknas

Den cyklomatiska komplexiteten beräknas genom att lägga till 1 till följande:

  • Antalet grenar (till exempel if, whileoch do).
  • Antalet case instruktioner i en switch.

Exempel

I följande exempel visas metoder som har varierande cyklomatiska komplexiteter.

Cyklomatisk komplexitet av 1

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

Cyklomatisk komplexitet av 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

Cyklomatisk komplexitet på 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

Cyklomatisk komplexitet på 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: Undvik överdrivet arv

Se även