CA1502:メソッドの実装を複雑にしすぎないでください

ルール ID CA1502
カテゴリ 保守容易性
修正が中断ありか中断なしか なし

原因

メソッドに、過剰なサイクロマティック複雑度があります。

規則の説明

サイクロマティック複雑度 は、線形独立のメソッド経路数を示す尺度で、条件分岐の数と複雑さによって決まります。 サイクロマティック複雑度が低いとは、一般に、そのメソッドが理解しやすく、テストおよび保守が容易であることを示しています。 サイクロマティック複雑度は、メソッドの制御フロー グラフから計算され、次のように算出されます。

サイクロマティック複雑度 = エッジの数 - ノードの数 + 1

ノード はロジックの分岐点を表し、エッジ はノード間の線を表します。

この規則は、サイクロマティック複雑度が 25 を超える場合に違反を報告します。

コード メトリックの詳細については、マネージ コードの複雑さの測定に関するページを参照してください。

違反の修正方法

この規則違反を修正するには、メソッドをリファクタリングして、サイクロマティック複雑度を下げます。

どのようなときに警告を抑制するか

複雑さを簡単に軽減できない場合、またメソッドが理解しやすく、テストおよび保守が容易に行える場合は、この規則による警告を抑制しても問題ありません。 特に、大規模な switch (Visual Basic では Select) ステートメントを含むメソッドは、除外の候補です。 開発サイクルの後半でコードベースの安定性を損なうリスクがある、または以前に出荷されたコードで実行時の動作に予期しない変更が発生してしまうリスクがあるならば、コードをリファクタリングすることによって保守容易性を向上させるよりも、それらのリスクを避ける方が良い場合があります。

サイクロマティック複雑度の計算方法

サイクロマティック複雑度は、次のように 1 を追加することによって計算されます。

  • 分岐の数 (ifwhiledo など)

  • switch における case ステートメントの数

使用例

次の例は、さまざまなサイクロマティック複雑度を持つメソッドを示しています。

サイクロマティック複雑度 1

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

サイクロマティック複雑度 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

サイクロマティック複雑度 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

サイクロマティック複雑度 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:継承を使用しすぎないでください

関連項目