-1

As per Wiki:

Cyclomatic complexity is a software metric, used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program's source code. It was developed by Thomas J. McCabe, Sr. in 1976.

Could this term apply to C# Linq with a lambda expression like this one:

_fred = fred.Where(c =>
    c.IsActive &&
    c.PriorityOrder.HasValue &&
(c.PriorityOrder == 0 || !(c.MinUnits == 0 && (!c.MaxUnits.HasValue || c.MaxUnits == 0))))
.GroupBy(x => x.Scope)
.ToDictionary(x => x.Key, x => x.ToList());

if so, what is the cyclomatic complexity of this bit of code and why does Resharper tells me it is.. 1?

Same piece of logic from the Where clause above broken down into multiple if statements shows cyclomatic complexity of 9. Why?

private IEnumerable<Priority> FilterPriorities(IEnumerable<Priority> priorities)
{
    var result = new List<Priority>();

    foreach (var p in priorities)
    {
        if (p.IsActive == false) continue;

        if (p.PriorityOrder.HasValue == false) continue;

        if (p.PriorityOrder == 0)
        {
            result.Add(p);
            continue;
        }

        if ((p.MinUnits == 0 && (!p.MaxUnits.HasValue || p.MaxUnits == 0)) == false)
        {
            result.Add(p);
        }
    }

    return result;
}
Ruslan
  • 9,927
  • 15
  • 55
  • 89
  • 1
    I see a single linear path through this code. Why do you think it shouldn't be `1`? –  Nov 03 '17 at 18:28
  • 1
    there is no branching here so I'm not sure why you expect it to be more complex. – Matthew Whited Nov 03 '17 at 18:28
  • 1
    Yep, you have a condition, but there is no `else`, so there's only one path. – Rufus L Nov 03 '17 at 18:31
  • 1
    Cyclomatic complexity doesn't include different paths taken inside function-calls. – Blorgbeard Nov 03 '17 at 18:31
  • 1
    @Tsar The fact of the matter is that it _isn't_ broken down into multiple nested `for`loops with `if/else`. – JLRishe Nov 03 '17 at 18:31
  • it doesn't look through method implementation.@Tsar – M.kazem Akhgary Nov 03 '17 at 18:32
  • `don't you think this Linq query broken down into multiple nested for loops ...` no, definitely not. Linq is a separate method, it will be pushed into stack before begin executed. – M.kazem Akhgary Nov 03 '17 at 18:33
  • If you want to know the cyclomatic complexity of the inner function, make it into a separate method and have ReSharper check that: `static bool MyClause(SomeType c) { return c.IsActive && c.PriorityOrder.HasValue && (c.PriorityOrder == 0 || !(c.MinUnits == 0 && (!c.MaxUnits.HasValue || c.MaxUnits == 0))); }` – JLRishe Nov 03 '17 at 18:43

1 Answers1

2

Cyclomatic complexity is not going to catch your LINQ expression as anything but a "simple" expression because that's what Cyclomatic complexity is defined to do.

If your expression can be understood/rewritten to be like this:

if (something)
    your_variable = this_thing;
else
    your_variable = this_other_thing;

then that's going to impact your cyclomatic complexity.

However, with LINQ, and most constructs using lambdas (which LINQ expressions are basically a syntax for creating), the compiler, and cyclomatic complexity analyzer, is going to see this:

your_variable = really_complex_expression;

So it's going to count that as 1 path through your code.


Whether or not we're going to need a different way of measuring complexity to handle this kind of thing is unknown (to me), but cyclomatic complexity is not it.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825