8

我々はsortof、このコードを持っている:VS10究極でイベントハンドラサブスクリプションが13個あるメソッドでは、循環的複雑さはどのように27になりますか?

private void InitializeEvents() 
{ 
    this.Event1 += (s,e) => { }; 
    this.Event2 += (s,e) => { }; 
    this.Event3 += (s,e) => { }; 
    this.Event4 += (s,e) => { }; 
    this.Event5 += (s,e) => { }; 
    this.Event6 += (s,e) => { }; 
    this.Event7 += (s,e) => { }; 
    this.Event8 += (s,e) => { }; 
    this.Event9 += (s,e) => { }; 
    this.Event10 += (s,e) => { }; 
    this.Event11 += (s,e) => { }; 
    this.Event12 += (s,e) => { }; 
    this.Event13 += (s,e) => { }; 
} 

コード分析は、 "27の循環的複雑度" を言います。線の1つを削除すると、循環的な複雑さが25になります。

これはどのように可能ですか?

答えて

17

コード分析では、ソースコードではなく、アセンブリ内のILを調べていることを思い出してください。 ILにネームでラムダ式をサポートするものは何もないので、それらはコンパイラの構築物です。 ouput hereの詳細を見つけることができます。しかし、基本的にラムダ式は、匿名のデリゲートであるプライベートな静的クラスに変わります。しかし、コードで参照されるたびに匿名のデリゲートのインスタンスを作成するのではなく、デリゲートがキャッシュされます。したがって、ラムダ式を割り当てるたびに、そのラムダデリゲートのインスタンスが作成されていることを確認するチェックが行われます。そうであれば、キャッシュされたデリゲートが使用されます。これはILでif/elseを生成し、複雑さを2だけ増加させます。したがって、この関数では、複雑さは1 + 2 *(λexpress)= 1 + 2 *(13)= 27で正しい数です。

+0

+1 "コード解析ではソースコードではなく、アセンブリ内のILを参照しています.Lambda式をネイティブサポートするILには何もありません" – Lijo

+0

Lambda/Delegateは閉鎖がない場合のみキャッシュされますそれらの上に。そうでなければ、そうではありません。これは(いくつかの)ラムダが高価である理由の1つです。 JIT、割り当て、GCも含まれていますが、それは別の議論です。私は、私が数えることができる "ホット"メソッドで閉鎖とlambdaに関連するより多くのパフォーマンスの問題を修正しました。 –

1

ベストの推測では、イベントアクセサ形式上の議論のためのhttp://msdn.microsoft.com/en-us/magazine/cc163533.aspxhttp://www.switchonthecode.com/tutorials/csharp-tutorial-event-accessors を参照してください

class MyClass 
{ 
    private event EventHandler MyPrivateEvent; 

    public event EventHandler MyEvent 
    { 
    add 
    { 
     MyPrivateEvent += value; 
    } 
    remove 
    { 
     MyPrivateEvent -= value; 
    } 
    } 
} 

VIZ、これはおそらくイベントアクセサ形式に変換されて上記の文が原因であるということです。

3

C#コンパイラは、実際にはlambdaを含む匿名メソッドに対してかなり興味深いILを生成します。それぞれに対して、プライベートフィールドを作成し、消費メソッドでその値を代入する前に、値がnullであるかどうかをチェックします。これはIf分岐をコンパイル済みメソッドに追加します。コードメトリクスツールはこれを無視する必要があります(http://social.msdn.microsoft.com/Forums/eu/vstscode/thread/8c17f569-5ee3-4d26-bf09-4ad4f9289705、https://connect.microsoft.com/VisualStudio/feedback/details/555560/method-using-many-lambda-expressions-causes-high-cyclomatic-complexity)。 。今のところ、偽陽性であると感じる場合、問題を無視する必要があります。

関連する問題