CA1502:避免过度复杂

类型名

AvoidExcessiveComplexity

CheckId

CA1502

类别

Microsoft.Maintainability

是否重大更改

非重大更改

原因

某方法具有过度的圈复杂度。

规则说明

“圈复杂度”通过方法来测量线性独立的路径的数量,该数量是由条件分支的数量和复杂度决定的。 较低的圈复杂度通常表示方法容易理解、测试和维护。 圈复杂度是通过方法的控件流图形计算的,计算公式如下:

圈复杂度 = 边数 - 节点数 + 1

其中节点表示逻辑分支点,边表示节点之间的直线。

当圈复杂度大于 25 时,该规则将报告冲突。

可以了解有关代码度量在 测量托管代码的复杂性和可维护性

如何解决冲突

要解决与该规则的冲突,请重构该方法,以减少其圈复杂度。

何时禁止显示警告

如果可以轻松地减少复杂度,并且很容易理解、测试和维护该方法,则可以安全地禁止显示与此规则有关的警告。 特别是当包含较大的 switch(在 Visual Basic 中为 Select)语句的方法是要排除的对象时。 与重构代码带来的可维护性好处相比,在以后的开发周期中破坏代码库的稳定性或者导致在以前发布的代码中的运行时行为发生意外变化的风险可能是得不偿失的。

圈复杂度的计算方法

圈复杂度的计算方法是向以下项加 1:

  • 分支数(如 if、while 和 do)

  • switch 中的 case 语句数。

下面的示例演示圈复杂度不断变化的方法。

示例

圈复杂度为 1

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

圈复杂度为 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!"); 
    } 
}

圈复杂度为 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!");
    }
}

圈复杂度为 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;
    }
}

相关规则

CA1501:避免过度继承

请参见

其他资源

测量托管代码的复杂性和可维护性