共用方式為


CA1502:避免過度複雜

型別名稱

AvoidExcessiveComplexity

CheckId

CA1502

分類

Microsoft.Maintainability

中斷變更

中斷

原因

方法的循環複雜度超過一般情況。

規則描述

「循環複雜度」(Cyclomatic Complexity) 會測量整個方法中線性獨立路徑的數目,此數目是由條件分支的數目與複雜度決定。較低的循環複雜度通常表示方法是易於了解、測試和維護。循環複雜度是從方法的控制流程圖計算得出,它的公式如下:

循環複雜度 = 邊緣數目 - 節點數目 + 1

其中 node 表示邏輯分支點,edge 則表示 node 之間的線。

當循環複雜度超過 25 時,此規則會報告違規情形。

您可以進一步了解程式碼度量。請參考 測量 Managed 程式碼的複雜度和維護性

如何修正違規

若要修正此規則的違規情形,請重構方法以降低循環複雜度。

隱藏警告的時機

如果無法輕易降低複雜度,而且方法也易於了解、測試和維護,則您可以放心地隱藏這項規則的警告。包含大型 switch (在 Visual Basic 中為 Select) 陳述式的方法尤其可以列為可排除的候選項目。在開發週期晚期變動程式碼基底 (Code Base),或是在先前送出之程式碼的執行階段行為中引入未預期的變更,這類的風險會比重構程式碼在維護方面所帶來的優點更加重要。

循環複雜度的計算方式

循環複雜度是藉由在下列各項中加 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:避免過度繼承

請參閱

其他資源

測量 Managed 程式碼的複雜度和維護性