为什么带有 `switch` 的代码的圈复杂度高于带有 'if-else' 的代码
Why cyclomatic complexity of code with `switch` higher than that of with 'if-else'
我有两个示例函数 TestComplexityIf
和 TestComplexitySwitch
。 VisualStudio-2017 'Calculate Code Metrics' 工具报告带有 switch
语句的函数的圈复杂度为 10,而带有 if-else
的函数的圈复杂度为 7。我想知道 TestComplexitySwitch() 的复杂度是如何计算的。
private static void TestComplexityIf(String arg)
{
if (arg == "a")
{ }
else if (arg == "b")
{ }
else if (arg == "c")
{ }
else if (arg == "d")
{ }
else if (arg == "d")
{ }
else if (arg == "f")
{ }
else if (arg == "g")
{ }
}
private static void TestComplexitySwitch(String arg)
{
switch (arg)
{
case "a":
break;
case "b":
break;
case "c":
break;
case "d":
break;
case "e":
break;
case "f":
break;
case "g":
break;
}
}
此外,如果我评论最后一个案例,复杂度突然变为 6。
private static void TestComplexitySwitch(String arg)
{
switch (arg)
{
case "a":
break;
case "b":
break;
case "c":
break;
case "d":
break;
case "e":
break;
case "f":
break;
//case "g":
//break;
}
}
Visual Studio 圈复杂度 (CC) 工具从 IL 代码计算值,因此受编译器详细信息的约束。
在这里您遇到了性能编译器的细节问题:当字符串上的 switch 严格超过 6 cases 时,编译器创建一个散列 table 用于快速字符串搜索。此散列 table 不会出现在 C# 代码中,而只会出现在 IL 代码中。 IL 代码变得更加复杂以处理此散列 table,并且您会得到意外的 CC 值。 this link from Michael Randall.
很好地说明了这种情况
或者,您可以使用 NDepend 工具 compute the CC from C# source code, visualize CC values in a colored treemap and run some rules to forbid too complex methods。
(免责声明我为 NDepend 工作)
我有两个示例函数 TestComplexityIf
和 TestComplexitySwitch
。 VisualStudio-2017 'Calculate Code Metrics' 工具报告带有 switch
语句的函数的圈复杂度为 10,而带有 if-else
的函数的圈复杂度为 7。我想知道 TestComplexitySwitch() 的复杂度是如何计算的。
private static void TestComplexityIf(String arg)
{
if (arg == "a")
{ }
else if (arg == "b")
{ }
else if (arg == "c")
{ }
else if (arg == "d")
{ }
else if (arg == "d")
{ }
else if (arg == "f")
{ }
else if (arg == "g")
{ }
}
private static void TestComplexitySwitch(String arg)
{
switch (arg)
{
case "a":
break;
case "b":
break;
case "c":
break;
case "d":
break;
case "e":
break;
case "f":
break;
case "g":
break;
}
}
此外,如果我评论最后一个案例,复杂度突然变为 6。
private static void TestComplexitySwitch(String arg)
{
switch (arg)
{
case "a":
break;
case "b":
break;
case "c":
break;
case "d":
break;
case "e":
break;
case "f":
break;
//case "g":
//break;
}
}
Visual Studio 圈复杂度 (CC) 工具从 IL 代码计算值,因此受编译器详细信息的约束。
在这里您遇到了性能编译器的细节问题:当字符串上的 switch 严格超过 6 cases 时,编译器创建一个散列 table 用于快速字符串搜索。此散列 table 不会出现在 C# 代码中,而只会出现在 IL 代码中。 IL 代码变得更加复杂以处理此散列 table,并且您会得到意外的 CC 值。 this link from Michael Randall.
很好地说明了这种情况或者,您可以使用 NDepend 工具 compute the CC from C# source code, visualize CC values in a colored treemap and run some rules to forbid too complex methods。
(免责声明我为 NDepend 工作)