我们有这样的代码,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。
有没有分支回事,所以这怎么可能?
Remeber该代码分析是在汇编,不是你的源代码,看IL。 有没有在本机支持lambda表达式的IL,所以他们是编译器的构造。 你可以找到什么是输出中的细节在这里 。 但基本上你的lambda表达式变成一个私有静态类,它是一个匿名deligate。 然而,而创造的匿名deligate每次在代码中引用时,deligate被缓存的实例。 所以,每次分配lambda表达式时,它做了检查,发现拉姆达deligate的一个实例被创建,如果是,则使用缓存deligate。 如果/否则在IL通过2.增加复杂生成因此,在这种功能的复杂性是1 + 2 *(拉姆达快递)= 1 + 2 *(13)= 27,其是正确的号码。
C#编译器实际上产生了匿名方法,包括lambda表达式一些相当“有趣” IL。 对于每一个,它创建一个私有字段然后,在消费方法分配它的值之前,它会检查是否值为空,这增加了一个如果分支到编译的方法。 该代码度量工具应该忽略这个(http://social.msdn.microsoft.com/Forums/eu/vstscode/thread/8c17f569-5ee3-4d26-bf09-4ad4f9289705, https://connect.microsoft.com/VisualStudio /反馈/信息/ 555560 /方法,使用一对多-拉姆达表达式死因,高圈复杂度 ),我们可以希望,最终会。 现在,你很可能,如果你觉得这是一个假阳性忽视的问题。
最好的猜测是,这可能是由于上述声明被转换为事件访问的格式,即
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?