我有一个(C#)函数,它检查四组条件并返回一个bool。如果其中任何一个为真,则返回true
。我确信我可以简化逻辑,但我希望它具有相当的可读性。
Visual Studio中的CodeMaid扩展并告诉我该函数的cylomatic复杂度为12. I looked it up并且cylomatic复杂度为
通过源代码的独立路径数
我不明白为什么会这样。我可以用两种方式来考虑它,或者说圈复杂度应该是2,因为它总是经过相同的路径但是可以返回{{1或true
。或者可以理解它是否是16,因为最后四个布尔值false
一起可以是真或假,2 * 2 * 2 * 2 = 16。
有人可以告诉我为什么它的12?甚至可能会显示一个图表,以便我可以看到不同的路径?
or
提前致谢。
修改
我把它改成了这个。为复选框条件分配局部变量并没有任何效果,但是从" YES" /" NO"中创建布尔值。把复杂性提高到14,我想我明白了。
public bool FitsCheckBoxCriteria(TaskClass tasks)
{
// note: bool == true/false comparisons mean you don't have to cast 'bool?' as bool
// if neither checkboxes are checked, show everything
bool showEverything = NoShutDownRequiredCheckBox.IsChecked == false &&
ActiveRequiredCheckBox.IsChecked == false;
// if both are checked, only show active non-shutdown tasks
bool showActiveNonShutdown = ActiveRequiredCheckBox.IsChecked == true &&
tasks.Active == "YES" &&
NoShutDownRequiredCheckBox.IsChecked == true &&
tasks.ShutdownRequired == "NO";
// if active is checked but shudown isn't, display all active
bool showActive = ActiveRequiredCheckBox.IsChecked == true &&
tasks.Active == "YES" &&
NoShutDownRequiredCheckBox.IsChecked == false;
// if non-shutdown is checked but active isn't, display all non-shutdown tasks
bool showNonShutdown = NoShutDownRequiredCheckBox.IsChecked == true &&
tasks.ShutdownRequired == "NO" &&
ActiveRequiredCheckBox.IsChecked == false;
return showEverything || showActiveNonShutdown || showActive || showNonShutdown;
}
答案 0 :(得分:3)
这只是一个猜测,但我认为分配是每个+2(if = true / else = false),然后在return语句中为每个可能的退出条件+1。所以它可能会放松到像:
bool showEverything = false;
if (...) { showEverything = true; } +1
else { showEverything = false; } +1
bool showActiveNonShutdown = ... +2 if/else
bool showActive = ... +2 if/else
bool showNonShutdown = ... +2 if/else
if (showEverything) {...} +1
else if (showActiveNonShutdown) {...} +1
else if (showActive) {...} +1
else if (showNonShutdown) {...} +1
else {false}
答案 1 :(得分:3)
关键在于“独立路径”。
我将重写你的代码以缩短它,以便我们讨论它。
public bool FitsCheckBoxCriteria(TaskClass tasks)
{
bool E1 = A1 && A2;
bool E2 = B1 && B2 && B3 && B4;
bool E3 = C1 && C2 && C3;
bool E4 = D1 && D2 && D3;
return E1 || E2 || E3 || E4;
}
Cyclomatic复杂性是独立路径的数量。这不是返回值的总可能数量(2)。
&&运算符和||操作员是短路操作;如果A1为假,则不评估 A2 。同样,如果E1为真,则不评估E2。
如果用&替换所有&& s;和所有|| s |在上面的代码中,圈复杂度为1,因为代码中只有一条路径。 (虽然这不会使代码变得更好)。
实际上,有72条可能的路径......
但路径4不包含任何尚未在先前路径上的新代码。这就是“独立路径”的定义 - 每条路径都必须包含新代码。
因此,在此示例中,您可以手动计算代码,如下所示:
1 +此代码中的短路运算符数(11)= 12.
{{3}}
答案 2 :(得分:2)
C#使用短路评估,这意味着如果有x && y
表达式y
仅在必要时进行评估,更准确地说,如果x
为真。这意味着result = x && y;
有两个独立的执行路径:(1)如果x
为false,则仅评估x
并且result
获取false值(不评估y
})但是(2)如果x
为真,则y
也会被评估,而result
会得到y
的评估结果。这意味着每个&&
和||
运算符都会增加圈复杂度,在第一个示例中,有8&&&和3 ||运算符因此该方法的圈复杂度为12。