CA1502: Evitare complessità eccessiva
TypeName |
AvoidExcessiveComplexity |
CheckId |
CA1502 |
Category |
Microsoft.Maintainability |
Breaking Change |
Non sostanziale |
Causa
Un metodo presenta una complessità ciclomatica eccessiva.
Descrizione della regola
La complessità ciclomatica misura il numero di percorsi linearmente indipendenti tramite il metodo, determinato dal numero e dalla complessità di rami condizionali. Una complessità ciclomatica bassa indica in genere un metodo di semplice comprensione, test e gestione. La complessità ciclomatica viene calcolata da un grafico di flusso di controllo del metodo ed è espressa nel modo seguente:
complessità ciclomatica = il numero di bordi - il numero di nodi + 1
dove un nodo rappresenta un punto di ramo logico e un margine rappresenta una linea tra nodi.
Quando la complessità ciclomatica è maggiore di 25, la regola segnala una violazione.
Come correggere le violazioni
Per correggere una violazione di questa regola, effettuare il refactoring del metodo per ridurne la complessità ciclomatica.
Esclusione di avvisi
È consigliabile non visualizzare un avviso di questa regola se non è possibile ridurre facilmente la complessità e se il metodo può essere compreso, testato e gestito senza problemi. In particolare, un metodo che contiene un'istruzione switch (Select in Visual Basic) di grandi dimensioni è adatto all'esclusione. Il rischio di destabilizzare la codebase in una fase avanzata del ciclo di sviluppo o di introdurre una modifica imprevista nel comportamento in fase di esecuzione nel codice precedentemente fornito può superare i vantaggi in termini di gestibilità derivanti dal refactoring del codice.
Calcolo della complessità ciclomatica
La complessità ciclomatica viene calcolata aggiungendo 1 agli elementi seguenti:
Numero di rami (ad esempio if, whilee do)
Numero di istruzioni case in switch
Negli esempi seguenti sono illustrati i metodi con varie complessità ciclomatiche.
Esempio
Complessità ciclomatica di 1
Public Sub Method()
Console.WriteLine("Hello World!")
End Sub
public void Method()
{
Console.WriteLine("Hello World!");
}
void Method()
{
Console::WriteLine("Hello World!");
}
Complessità ciclomatica di 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!");
}
}
Complessità ciclomatica di 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!");
}
}
Complessità ciclomatica di 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;
}
}