6

Metrics are calcucated using Visual Studio.

First method has CC = 4

    private IEnumerable<string> GetRows(DataTable dt, string columnDelimiter)
    {
        return from DataRow row in dt.Rows
               select string.Join(columnDelimiter, row.ItemArray.Select(k => k.ToString()));
    }

Second method has CC = 5.

    private IEnumerable<string> GetRowsForeach(DataTable dt, string columnDelimiter)
    {
        var rows = new List<string>();
        foreach (DataRow row in dt.Rows)
        {
            var rowString = string.Join(columnDelimiter, row.ItemArray.Select(k => k.ToString()));
            rows.Add(rowString);
        }

        return rows;
    }

I'd say that first method should have CC = 1 and second maybe CC = 1 or maybe 2 (understanding foreach as for with end condition. But I would never say their CC is so high. What am I misunderstanding?

Piotr Perak
  • 10,718
  • 9
  • 49
  • 86
  • 6
    It probably counts the anonymous function and the code generated by LINQ. – Tilo Dec 09 '13 at 22:25
  • @Tilo it used to be much worse as it also counted the boiler plate code generated by lync. But indeed, the Linq statement add's complexity, it's basically its own foreach, regardless of how simple it looks. – jessehouwing Dec 09 '13 at 22:33
  • @Tilo: Your answer made me think about it differently. I thought it scanned my source code, not my IL. So because you were first If you post your comment as an answer I will accept it. – Piotr Perak Dec 10 '13 at 07:44

2 Answers2

3

It is an imperfect tool. It sees IL, the code that's generated by the C# compiler. It does not see your code. And there is plenty of syntax sugar in C# that was designed to make your code simple to understand but has an iceberg of code-gen below the water-line. Query comprehensions certainly fit that pattern.

Use CC only as a guide, never let it set the rules and never let it cramp your style. Your brain outsmarts any tool.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I only wanted to show to my colleagues that my refactored method has a CC a lot lower then method before refactoring (CC=9) and was suprised that I achieved CC=5. – Piotr Perak Dec 10 '13 at 07:47
2

Apparently it is due to the fact that every IEnumerator generated using linq methods will also implement an IDisposable, that in order to be freed correctly will wrap the code in a try..catch block.

here there is a good explanation.

In your first example you have two select statements along with a join, hence the count of 4.

LazyOfT
  • 1,428
  • 7
  • 20