CA1502: Evitar una complejidad excesiva

Propiedad Value
Identificador de la regla CA1502
Título Evitar una complejidad excesiva
Categoría Capacidad de mantenimiento
La corrección es problemática o no problemática Poco problemático
Umbral predeterminado 25
Habilitado de forma predeterminada en .NET 8 No

Causa

Un método tiene una complejidad ciclomática excesiva.

Descripción de la regla

La complejidad ciclomática mide el número de rutas de acceso independientes de forma lineal a través del método, que es determinado por el número y la complejidad de bifurcaciones condicionales. Generalmente, una complejidad ciclomática baja indica un método que es fácil de entender, probar y mantener. La complejidad ciclomática se calcula a partir de un gráfico de flujo de control del método y se proporciona de la siguiente manera:

complejidad ciclomática = el número de límites - el número de nodos + 1

Un nodo representa un punto de bifurcación lógico y un borde representa una línea entre los nodos.

La regla notifica una infracción cuando la complejidad ciclomática de un método es superior a 25. Sin embargo, puede configurar el umbral y especificar también otros tipos de símbolos que la regla debe analizar.

Puede obtener más información sobre las métricas del código en Cálculo de la complejidad del código administrado.

Cómo corregir infracciones

Para corregir una infracción de esta regla, refactorice el método para reducir su complejidad ciclomática.

Cuándo suprimir las advertencias

Es seguro suprimir una advertencia de esta regla si la complejidad no se puede reducir fácilmente y el método es fácil de entender, probar y mantener. En concreto, un método que contiene una instrucción switch grande (Select en Visual Basic) es un candidato para la exclusión. El riesgo de desestabilizar el código base más adelante durante el ciclo de desarrollo o la introducción de un cambio inesperado en el comportamiento en tiempo de ejecución en el código enviado anteriormente podría superar las ventajas de mantenimiento de la refactorización del código.

Nota

Es posible que vea advertencias de falsos positivos de esta regla si se aplica todo lo siguiente:

  • Está usando Visual Studio 2022, versión 17.5 o posterior, con una versión anterior del SDK de .NET, es decir, .NET 6 o una anterior.
  • Está usando los analizadores del SDK de .NET 6 o una versión anterior de los paquetes del analizador, como Microsoft.CodeAnalysis.FxCopAnalyzers.

Los falsos positivos se deben a un cambio importante en el compilador de C#. Considere la posibilidad de usar un analizador más reciente que incluya la corrección de las advertencias de falsos positivos. Actualice a Microsoft.CodeAnalysis.NetAnalyzers, versión 7.0.0-preview1.22464.1 o posterior, o bien use los analizadores del SDK de .NET 7.

Supresión de una advertencia

Si solo quiere suprimir una única infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y volver a habilitar la regla.

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

Para deshabilitar la regla de un archivo, una carpeta o un proyecto, establezca su gravedad en none del archivo de configuración.

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

Para obtener más información, consulte Procedimiento para suprimir advertencias de análisis de código.

Configuración del umbral

Puede configurar el umbral en el que se activa esta regla y los tipos de símbolos que se van a analizar. Los tipos de símbolos permitidos son:

  • Assembly
  • Namespace
  • Type
  • Method
  • Field
  • Event
  • Property
  1. Cree un archivo de texto denominado CodeMetricsConfig.txt.

  2. Agregue el umbral deseado al archivo de texto con el formato siguiente:

    CA1502: 10
    

    En este ejemplo, la regla se configura para activarse cuando la complejidad ciclomática de un método es mayor que 10.

    CA1502(Type): 4
    

    En este ejemplo, la regla se configura para activarse cuando la complejidad ciclomática de un tipo es mayor que 4. Con este archivo de configuración, la regla seguiría notificando métodos con una complejidad ciclomática mayor que la predeterminada (25).

  3. En el archivo del proyecto, marque la acción de compilación del archivo de configuración como AdditionalFiles. Por ejemplo:

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

Cálculo de la complejidad ciclomática

La complejidad ciclomática se calcula sumando 1 a lo siguiente:

  • El número de ramas (como if, while y do).
  • El número de instrucciones case en switch.

Ejemplos

En los ejemplos siguientes se muestran métodos que tienen diferentes complejidades ciclomáticas.

Complejidad ciclomática de 1

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

Complejidad ciclomática de 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

Complejidad ciclomática de 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

Complejidad ciclomática de 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: Evitar una herencia excesiva

Consulte también