Question

Does LINQ and Lambda expressions reduce cyclomatic-complexity? Just curious because CodeRush actually shows a reduction in cc when the VS analyzer increases it.

Was it helpful?

Solution

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 :)

OTHER TIPS

I just came around with the same question and, in fact, lambda can increase the cyclomatic complexity. I did the test and Where() clauses can increase it sensibly.

Readability is indeed one of your top priorities.

But it didn't take me to long to replace some LinQ queries by Get() methods which provided me with the same data and extra benefits.


I keep my Fxcop on in my build/publish script so I never deploy something without reaching the target of 25 for cyclomatic complexity.

It's tough, but I think it's worth the effort.

This grants me some points in discussions when my mates come with a very bad code saying: this works, that's what matters.


my tip is: keep your cyclomatic complexity below 25. this may help you to keep every method simple enough for good maintenance.

Jon Skeet pretty much answered the question succinctly. I would like to add that in my experience with high-level languages like C#, the value of measuring cyclomatic complexity is reduced because of the value that syntactic sugar packages like LINQ adds to development.

Over the past ten years, as languages have evolved, many on the net have illustrated a strong correlation between cyclomatic complexity and lines of code, making many of them question just how much value such a measure actually brings. Another way to look at it would be that the devaluation of CC as a measure of code quality is actually an assertion of the importance of readability, as one is often the inverse of the other.

For example, if I put a conditional inside a foreach loop, the conditional is evaluated as my code, and the appropriate number of code paths is counted. On the other hand, if I apply a function tree to the collection I am iterating over (e.g. Where(evalStr => evalStr == origStr) I am moving the conditional to the outside of the loop and into compiler-generated code. There are still the same number of branches, however the conditionals are not part of the loop, yet the CC increases beyond that of the foreach loop, with "penalties" for using anonymous methods (lambdas and delegates) on top of the actual branch count. The Where function lets me precondition the iterated collection so that the loop only iterates if it needs to.

However, the code is far and away more readable.

Finally, if one decides that a Boolean expression used inside a LINQ IQueryable function does not need to be unit tested, ostensibly because if there is an exception, it is a higher-order (a.k.a. business-level) exception (wrong value being tested, wrong operator, wrong operand, etc.) as opposed to a less-than-ideal use of the language (using switch instead of if, if instead of ternary, etc.) then measuring cyclomatic complexity should take this into account: A Where( ) function should not increase my CC. Measuring cyclomatic complexity won't help make better code; if anything, it will artificially increase a developer's tendency to simplify where no simplification may be necessary or desired.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top