-->

圈复杂度如何能在27与13的事件处理程序订阅的方法?(How can the cyclomatic

2019-07-29 01:52发布

我们有这样的代码,sortof:

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) => { };
}

在VS10终极标准分析说“的27圈复杂度”。 删除线之一,使圈复杂度25。

有没有分支回事,所以这怎么可能?

Answer 1:

Remeber该代码分析是在汇编,不是你的源代码,看IL。 有没有在本机支持lambda表达式的IL,所以他们是编译器的构造。 你可以找到什么是输出中的细节在这里 。 但基本上你的lambda表达式变成一个私有静态类,它是一个匿名deligate。 然而,而创造的匿名deligate每次在代码中引用时,deligate被缓存的实例。 所以,每次分配lambda表达式时,它做了检查,发现拉姆达deligate的一个实例被创建,如果是,则使用缓存deligate。 如果/否则在IL通过2.增加复杂生成因此,在这种功能的复杂性是1 + 2 *(拉姆达快递)= 1 + 2 *(13)= 27,其是正确的号码。



Answer 2:

C#编译器实际上产生了匿名方法,包括lambda表达式一些相当“有趣” IL。 对于每一个,它创建一个私有字段然后,在消费方法分配它的值之前,它会检查是否值为空,这增加了一个如果分支到编译的方法。 该代码度量工具应该忽略这个(http://social.msdn.microsoft.com/Forums/eu/vstscode/thread/8c17f569-5ee3-4d26-bf09-4ad4f9289705, https://connect.microsoft.com/VisualStudio /反馈/信息/ 555560 /方法,使用一对多-拉姆达表达式死因,高圈复杂度 ),我们可以希望,最终会。 现在,你很可能,如果你觉得这是一个假阳性忽视的问题。



Answer 3:

最好的猜测是,这可能是由于上述声明被转换为事件访问的格式,即

class MyClass
{
  private event EventHandler MyPrivateEvent;

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

见http://msdn.microsoft.com/en-us/magazine/cc163533.aspx和http://www.switchonthecode.com/tutorials/csharp-tutorial-event-accessors有关事件访问格式的讨论。



文章来源: How can the cyclomatic complexity be 27 in a method with 13 event handler subscriptions?