Vb.net 当使用其他相关因素重新排列switch语句时,为什么圈复杂度会发生变化?
以下方法的CC将生成为9Vb.net 当使用其他相关因素重新排列switch语句时,为什么圈复杂度会发生变化?,vb.net,.net-3.5,code-metrics,cyclomatic-complexity,select-case,Vb.net,.net 3.5,Code Metrics,Cyclomatic Complexity,Select Case,以下方法的CC将生成为9 Public Enum Fruits Apple Pineapple Banana PassionFruit Orange Melon Grape Mango End Enum Private Function Fruity(ByVal fruitType As Fruits) Select Case
Public Enum Fruits
Apple
Pineapple
Banana
PassionFruit
Orange
Melon
Grape
Mango
End Enum
Private Function Fruity(ByVal fruitType As Fruits)
Select Case fruitType
Case Fruits.Orange, Fruits.Banana
Case Fruits.Melon
Case Fruits.Mango
Case Fruits.Pineapple
Case Fruits.Passionfruit
Case Fruits.Melon, Fruits.Apple
End Select
End Function
但当枚举成员值由用户定义时,该方法的CC furty增加到14
Public Enum Fruits
Apple = 1
Pineapple = 3
Banana = 4
Passionfruit = 5
Orange = 7
Melon = 9
Grape = 11
Mango = 13
End Enum
现在让我们假设我将select case语句更改如下,然后方法FROUTHY的CC更改为7,但与上面的select case相比,可维护性指数略有下降
Select Case true
Case fruitType= Fruits.Orange or fruitType= Fruits.Banana
Case fruitType=Fruits.Melon
Case fruitType=Fruits.Mango
Case fruitType=Fruits.Pineapple
Case fruitType=Fruits.Passionfruit
Case fruitType=Fruits.Melon, Fruits.Apple
End Select
在最后一个场景中,我将参数的数据类型更改为integer,并访问另一个名为Vescelles的枚举,该枚举的值为50。现在,该方法的CC Fruity飙升至52。但是,如果我将Potato的值更改为0或1,那么CC将保持在15
Public Enum Vegetables
Potato = 50
End Enum
Private Function Fruity(ByVal fruitType As Integer)
Select Case fruitType
Case Fruits.Orange, Fruits.Banana
Case Fruits.Melon
Case Fruits.Mango
Case Vegetables.Potato
Case Fruits.Passionfruit
Case Fruits.Melon, Fruits.Apple
End Select
End Function
这些都是在VS2008团队系统版3.5SP1中测试的。我想知道为什么在这4种情况下CC会出现波动
这与下面给出的第二点有关吗?因为如果我在第四个场景中删除掉掉掉下来的案例,CC会下降到9。那么这是VS2008中的一个bug吗
关于VisualStudio2010的特别说明
使用Visual Studio 2010计算代码度量时,可能存在不适用于Visual Studio 2008的差异。在线文档给出了以下原因:
该函数包含一个或多个catch块。在Visual Studio的早期版本中,捕捉块未包含在计算中。在VisualStudio2010中,每个catch块的复杂性被添加到函数的复杂性中
该函数在VB语句中包含开关选择大小写。VisualStudio2010和早期版本之间的编译器差异可能会为某些包含失败案例的switch语句生成不同的MSIL代码
圈复杂度计数是一个相当简单的特性,它只计算从代码生成的IL中出现的分支数。每个分支将计数增加1 要查看该IL,请从VisualStudio命令提示符运行。当您比较这些不同代码段的IL时,很明显复杂性计数会发生这样的变化 您的第一个版本为每个枚举生成一个包含一个条目的。switch表中的每个条目对应一个Case语句,并将复杂性计数增加1 下一个版本将增加开关表的大小。它为缺少的枚举值添加条目。这不适当地增加了复杂性计数,该工具只是不够聪明,无法识别虚拟条目,而且不容易识别 您的上一个版本在枚举值中有太多的间隙。编译器识别出操作码.Switch不再有效,并使用一系列If/ElseIf测试生成完全不同的代码。降低复杂性计数。 仅将圈复杂度作为一个粗略的准则,它还不够复杂,无法证明剧烈的代码更改是合理的