CA1502: Evitare complessità eccessiva

Proprietà valore
ID regola CA1502
Titolo Evitare complessità eccessiva
Categoria Gestibilità
Correzione che causa un'interruzione o un'interruzione Nessuna interruzione
Soglia predefinita 25
Abilitato per impostazione predefinita in .NET 8 No

Causa

Un metodo ha una complessità ciclomatica eccessiva.

Descrizione regola

La complessità ciclomatica misura il numero di percorsi linearmente indipendenti attraverso il metodo , determinato dal numero e dalla complessità dei rami condizionali. Una bassa complessità ciclomatica indica in genere un metodo facile da comprendere, testare e gestire. La complessità ciclomatica viene calcolata da un grafico del flusso di controllo del metodo e viene fornito come segue:

complessità ciclomatica = numero di archi - numero di nodi + 1

Un nodo rappresenta un punto di diramazione logica e un bordo rappresenta una linea tra i nodi.

La regola segnala una violazione quando la complessità ciclomatica di un metodo è superiore a 25. Tuttavia, è possibile configurare la soglia e specificare anche altri tipi di simboli che la regola deve analizzare.

Per altre informazioni sulle metriche del codice, vedere Misurare la complessità del codice gestito.

Come correggere le violazioni

Per correggere una violazione di questa regola, effettuare il refactoring del metodo per ridurre la complessità ciclomatica.

Quando eliminare gli avvisi

È sicuro eliminare un avviso da questa regola se la complessità non può essere facilmente ridotta e il metodo è facile da comprendere, testare e gestire. In particolare, un metodo che contiene un'istruzione di grandi dimensioni switch (Select in Visual Basic) è un candidato per l'esclusione. Il rischio di destabilizzare la codebase in ritardo nel ciclo di sviluppo o di introdurre una modifica imprevista nel comportamento di runtime nel codice fornito in precedenza potrebbe superare i vantaggi di gestibilità del refactoring del codice.

Nota

Se si applicano tutti gli avvisi seguenti, è possibile che vengano visualizzati avvisi falsi positivi da questa regola:

  • Si usa Visual Studio 2022 versione 17.5 o successiva con una versione precedente di .NET SDK, ovvero .NET 6 o versioni precedenti.
  • Si usano gli analizzatori di .NET 6 SDK o una versione precedente dei pacchetti analizzatori, ad esempio Microsoft.CodeAnalysis.FxCopAnalyzers.

I falsi positivi sono dovuti a una modifica che causa un'interruzione nel compilatore C#. Prendere in considerazione l'uso di un analizzatore più recente che contiene la correzione per gli avvisi falsi positivi. Eseguire l'aggiornamento a Microsoft.CodeAnalysis.NetAnalyzers versione 7.0.0-preview1.22464.1 o successiva o usare gli analizzatori di .NET 7 SDK.

Eliminare un avviso

Se si vuole eliminare una singola violazione, aggiungere direttive del preprocessore al file di origine per disabilitare e quindi riabilitare la regola.

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

Per disabilitare la regola per un file, una cartella o un progetto, impostarne la gravità none su nel file di configurazione.

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

Per altre informazioni, vedere Come eliminare gli avvisi di analisi del codice.

Configurare la soglia

È possibile configurare la soglia in corrispondenza della quale viene attivata questa regola e i tipi di simboli da analizzare. I tipi di simboli consentiti sono:

  • Assembly
  • Namespace
  • Type
  • Method
  • Field
  • Event
  • Property
  1. Creare un file di testo denominato CodeMetricsConfig.txt.

  2. Aggiungere la soglia desiderata al file di testo nel formato seguente:

    CA1502: 10
    

    In questo esempio la regola viene configurata per l'avvio quando la complessità ciclomatica di un metodo è maggiore di 10.

    CA1502(Type): 4
    

    In questo esempio la regola viene configurata per l'avvio quando la complessità ciclomatica di un tipo è maggiore di 4. Con questo file di configurazione, la regola continuerà a segnalare i metodi con una complessità ciclomatica maggiore del valore predefinito (25).

  3. Nel file di progetto contrassegnare l'azione di compilazione del file di configurazione come AdditionalFiles. Ad esempio:

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

Come viene calcolata la complessità ciclomatica

La complessità ciclomatica viene calcolata aggiungendo 1 ai seguenti:

  • Numero di rami , ad esempio if, whilee do.
  • Numero di case istruzioni in un oggetto switch.

Esempi

Negli esempi seguenti vengono illustrati i metodi con complessità ciclomatiche variabili.

Complessità ciclomatica di 1

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

Complessità ciclomatica di 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

Complessità ciclomatica di 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

Complessità ciclomatica di 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: Evitare ereditarietà eccessiva

Vedi anche