0

I am trying to simplify some of my code (right now I'm at the cyclomatic complexity and class coupling part) and I am having an issue with the class coupling metric...

This is the scenario:

public class firstTestClass
    {
        public string Name { get; set; }
    }

public class secondTestClass
{
    public List<firstTestClass> _list = new List<firstTestClass>();
    public void testMethod()
    {
        string agg = string.Empty;
        //code goes here
    }
}

When I add this part, I have a class coupling of 4 on the testMethod()

foreach (firstTestClass cls in _list)
{
    agg += cls.Name;
}

but when I switch to simple for, the class coupling is reduced to 2

for (int i = 0; i < _list.Count; i++)
    {
        firstTestClass cls = _list[i];
        agg += cls.Name;
    }

I am thinking that the foreach is behind this, but I can't reasonably explain why/how these extra two couplings happen...

PS. I used Visual Studio 2013 Pro, Update 4 for this example...

tolanj
  • 3,651
  • 16
  • 30
norb
  • 165
  • 2
  • 11
  • code metrics are not holy, they don't replace the designer. – Philip Stuyck Feb 20 '15 at 09:26
  • 2
    for and foreach loops produce different IL code; foreach involves IEnumerator. so metrics are different – ASh Feb 20 '15 at 09:30
  • @ASh, thanks, this is the answer, I just did not know where to look... btw, how can I mark this as answer ? – norb Feb 20 '15 at 13:49
  • @PhilipStuyck they are not, but that doesn't mean I shouldn't take time to understand them better... fyi: I see no difference between these code fragments (speaking as a simple developer, and in this case, of course) – norb Feb 20 '15 at 13:51
  • A bad designer would conclude not to use a foreach loop anymore because the code complexity is higher. That is the point I am trying to make here. – Philip Stuyck Feb 20 '15 at 14:17
  • @PhilipStuyck 90% agree with you, although with low enough liberty, some might be forced into this decision; I haven't seen check-in policies based on metrics yet, but I wouldn't be surprised if this would be practiced in some places – norb Feb 20 '15 at 14:37
  • @norb: this is a good reason to calculate metrics from source code (written by you), and not from IL code (created by the compiler)... – Rudolf FERENC Feb 23 '15 at 07:42

1 Answers1

0

I think it can be even more simplified (probably reducing the complexity) by instead of

foreach (firstTestClass cls in _list)
{
    agg += cls.Name;
}

Use

agg = (from l in _list select l.Name).ToList().Join("");

(I don't have a compiler at hand, so code is not tested)

The reason for your class coupling might be extra classes used internally by the foreach loop (and not being used in the for loop). I do not know about this solution, but clear code is more important than code complexity.

DavidG
  • 113,891
  • 12
  • 217
  • 223
Michel Keijzers
  • 15,025
  • 28
  • 93
  • 119
  • " clear code is more important than code complexity"..I believe this totally subjective to project requirements.. – apomene Feb 20 '15 at 09:37
  • I tried the the slightly altered _string.Join("", ((from l in _list select l.Name).ToList()));_ approach and gave me worst complexity (3) and similar coupling (4) as the first example. Also, I could not get your suggestion to compile in a new 4.5.1 Console app. – norb Feb 20 '15 at 13:53
  • @apomene: Unfortunately 99% of the time the _stakeholders_ don't really care about such minor details as clear code... Most of the time they don't bother with metrics, either... – norb Feb 20 '15 at 13:57