C# 为什么这个函数的复杂性是12?
我有一个(C#)函数,它检查四组条件并返回bool。如果其中任何一个为true,则返回C# 为什么这个函数的复杂性是12?,c#,complexity-theory,cyclomatic-complexity,C#,Complexity Theory,Cyclomatic Complexity,我有一个(C#)函数,它检查四组条件并返回bool。如果其中任何一个为true,则返回true。我相信我可以简化逻辑,但我希望它相当可读 Visual Studio中的CodeMaid扩展告诉我函数的柱面复杂性是12。我和圆柱的复杂性是 通过源代码的独立路径数 我不明白为什么是12。我可以从两个方面考虑,圈复杂度应该是2,因为它总是通过相同的路径,但可能返回true或false。或者可以理解它是16,因为最后四个布尔值加在一起可能是真的,也可能是假的,2*2*2*2=16 有人能告诉我为什么是1
true
。我相信我可以简化逻辑,但我希望它相当可读
Visual Studio中的CodeMaid扩展告诉我函数的柱面复杂性是12。我和圆柱的复杂性是
通过源代码的独立路径数
我不明白为什么是12。我可以从两个方面考虑,圈复杂度应该是2,因为它总是通过相同的路径,但可能返回true
或false
。或者可以理解它是16,因为最后四个布尔值加在一起可能是真的,也可能是假的,2*2*2*2=16
有人能告诉我为什么是12点吗?甚至可以显示一个图表,这样我就可以直观地看到不同的路径了
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;
}
提前谢谢
编辑:
我把它改成了这个。为复选框条件指定局部变量没有任何效果,但通过“是”/“否”创建布尔值将复杂性提高到14,我想我理解这一点
public bool FitsCheckBoxCriteria(LubeTask tasks)
{
bool noShutdownReqChecked = (bool)NoShutDownRequiredCheckBox.IsChecked;
bool activeChecked = (bool)ActiveRequiredCheckBox.IsChecked;
bool active = tasks.Active == "YES" ? true : false;
bool shutdownReq = tasks.ShutdownRequired == "YES" ? true : false;
// if neither checkboxes are checked, show everything
bool showEverything = !noShutdownReqChecked && !activeChecked;
// if both are checked, only show activeChecked non-shutdown tasks
bool showActiveNonShutdown = activeChecked && noShutdownReqChecked && active && !shutdownReq;
// if activeChecked is checked but shudown isn't, display all activeChecked
bool showActive = activeChecked && !noShutdownReqChecked && active;
// if non-shutdown is chceked but activeChecked isn't, display all non-shutdown tasks
bool showNonShutdown = noShutdownReqChecked && !activeChecked && !shutdownReq;
return showEverything || showActiveNonShutdown || showActive || showNonShutdown;
}
这只是一个猜测,但我认为对于return语句中的每个可能的退出条件,赋值都是+2(if=true/else=false),然后是+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}
C#使用短路求值,这意味着如果存在x&&y
表达式,则只有在必要时才对y
求值,更准确地说,如果x
为真。这意味着result=x&&y
有两个独立的执行路径:(1)如果x
为false,则只计算x
,并且result
获得false值(不计算y
),但是(2)如果x
为true,则也计算y
并且result
获得y
的计算结果。这意味着每个&
和|
运算符都会增加圈复杂度,在第一个示例中,有8个&&&和3个| |运算符,因此该方法的圈复杂度为12。关键在于“独立路径”
我将重写您的代码以缩短它,以便我们可以讨论它
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;
}
圈复杂度是独立路径的数量。这不是返回值(2)的可能总数
&&运算符和| |运算符是短路操作;如果A1为假,则不计算A2。类似地,如果E1为真,则不计算E2
如果在上面的代码中用&替换所有的&&s,用|替换所有的| | s,圈复杂度为1,因为代码中只有一条路径。
(但这并不能使它更好地编写代码)
事实上,有72条可能的路径
这是一种非常有趣的看待它的方式!奇怪的是,如果删除所有
==true
语句并将==false
更改为,复杂性会发生什么变化代码>?他们是redundant@moarboilerplate我知道它们是多余的。只是这些类型是bool?
而不是bool
,所以为了可读性起见,我没有将它们全部转换,而是进行了比较。是的,但它对复杂性有什么影响?另外,如果您有兴趣优化它,我会使用标志枚举和逐位操作为每一位设置权限(尽管这会消除布尔值的可空性)嗯,我去掉了比较并进行了强制转换,这并没有改变复杂性。不过,这会很好。