Refactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed.

Cognitive Complexity, Because Testability != Understandability

Cyclomatic Complexity   

Cognitive Complexity

With those rules in mind, let's take another look at those first two methods:

 

As I mentioned, one of the biggest beefs with Cyclomatic Complexity has been its treatment of switch statements. Cognitive Complexity, on the other hand, only increments once for the entire switch structure, cases and all. Why? In short, because switches are easy, and Cognitive Complexity is about estimating how hard or easy control flow is to understand.

On the other hand, Cognitive Complexity increments in a familiar way for the other control flow structures: for, while, do while, ternary operators, if/#if/#ifdef/..., else if/elsif/elif/..., and else, as well as for catch statements. Additionally, it increments for jumps to labels (goto, break, and continue) and for each level of control flow nesting:

 As you can see, Cognitive Complexity takes into account the things that make this method harder to understand than getWords - the nesting and the continue to a label. So that while the two methods have equal Cyclomatic Complexity scores, their Cognitive Complexity scores clearly reflect the dramatic difference between them in understandability.

 

In looking at these examples, you may have noticed that Cognitive Complexity doesn't increment for the method itself. That means that simple domain classes have a Cognitive Complexity of zero:

 

 So now class-level metrics become meaningful. You can look at a list of classes and their Cognitive Complexity scores and know that when you see a high number, it really means there's a lot of logic in the class, not just a lot of methods.

 

PDF https://www.sonarsource.com/docs/CognitiveComplexity.pdf

 Sequences of logical operators

For similar reasons, Cognitive Complexity does not increment for each binary logical operator. Instead, it assesses a fundamental increment for each sequence of binary logical operators.

For instance, consider the following pairs:

a && ba && b && c && d

a || ba || b || c || d

Understanding the second line in each pair isn’t that much harder than understanding the first.

On the other hand, there is a marked difference in the effort to understand the following two lines:

a && b && c && d

a || b && c || d

Because boolean expressions become more difficult to understand with mixed operators, Cognitive complexity increments for each new sequence of like operators. For instance

 

优化的话,只能把复杂的部分,拆分到另外一个方法里面。然后让原来的方法调用新的方法。

https://www.cnblogs.com/chucklu/p/12671821.html  只要是调用深度不是层层嵌套,就还可以接受

 

How can the cyclomatic complexity be 27 in a method with 13 event handler subscriptions?

Remember that the Code Analysis is looking at the IL in your assembly, not your source code. There is nothing in the IL that natively supports lambda expressions, so they are a construct of the compiler. You can find the specifics of what is ouput here. But basically your lambda expression is turned into a private static class that is an anonymous deligate. However, rather that create an instance of the anonymous deligate every time it is referenced in code, the deligate is cached. So each time you assign a lambda expression, it does a check to see an instance of that lambda deligate has been created, if so it uses the cached deligate. That generates an if/else in the IL increasing the complexity by 2. So in this functions complexity is 1 + 2*(lambda express) = 1 + 2 *(13) = 27 which is the correct number.

 

Does LINQ and Lambda expressions reduce Cyclomatic-complexity?

I suspect that the discrepancy may be due to deferred execution. When you use LINQ with lambda expressions, you're specifying code which will be run if you then iterate over the collection.

Personally I'm not so worried about cyclomatic complexity, but I'm absolutely sure that (when used appropriately) LINQ improves readability. That's what I really care about :)

 

3 Tips To Reduce Cyclomatic Complexity In C#

Tip #1 – SWITCH/CASE
 
Avoid use of switch/case statements in your code. Use Factory or Strategy design patterns instead.
不过目前的sonarqube扫描,会把switch case的复杂度算成1
 
Tip #2 – IF Expressions
Reduce IF expressions in your code. Use the Single Responsibility principle for extracting a piece of code to other methods and make the method for just one responsibility. That change will reduce Cyclomatic Responsibility and improve maintainability for your code.
 
Tip #3 – BE COOL
Don't kill yourself because of Cyclomatic Complexity.
 
It’s better to keep your code simple and follow single responsibility principles than refactoring all your code making it hard to understand.
 
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” Martin Fowler.
 
Adopt an acceptable metric of CC(cyclomatic complexity) for your business and your daily life. This article is a guide for you, not a rule.

 

 

 

 

 

 

作者:Chuck Lu    GitHub    
posted @   ChuckLu  阅读(6702)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2019-04-09 sonarqube中new issue的标准
2019-04-09 Custom Quality Profiles in SonarQube
2019-04-09 命令行工具比较 cmd tools comparison
2019-04-09 Hyper
点击右上角即可分享
微信分享提示