C# Properties and standard class structural metrics

173 views Asked by At

I'm trying to understand how the elementary class structural metrics, such as ATFD (access to foreign data) and LCOM (lack of cohesion in methods) are calculated in light of C# Properties.

If a method access a single property of another class, does that mean that the ATFD score of that method is 1? Does this change based on whether there is a backing private field or not?

For LCOM, does the property count as a field or as a method (or as both) when following the formula laid out by NDepend for example https://www.ndepend.com/docs/code-metrics#LCOM.

How does this change when we have an explicit private field related to the property - i.e., what is the LCOM difference for the following classes A and C:

   class A {
      private int _b;
      private int _bx;
      public int B { get { return this._b; }
         set { this._b = value; }
      }

      public void MethodA() {
         B = 1;
      }

      public void MethodB() {
         this._bx = 1;
      }
   }

   class C {
      public int B { get; set; }
      public int Bx { get; set; }

      public void MethodA() {
         B = 1;
      }

      public void MethodB() {
         Bx = 1;
      }
   }
1

There are 1 answers

3
Patrick from NDepend team On

I modified the code in the question to make it compilable.

With NDepend, values for these 2 classes are:

class A   LCOM 0.7  LCOMHS 0.88
class C   LCOM 0.0  LCOMHS 0.0

For LCOM, does the property count as a field or as a method (or as both)

This is answered in the LCOM/LCOMHS documentation

  • LCOM = 1 – (sum(MF)/M*F)
  • LCOM HS = (M – sum(MF)/F)(M-1)

Where:

  • M is the number of methods in class (both static and instance methods are counted, it includes also constructors, properties getters/setters, events add/remove methods).
  • F is the number of instance fields in the class.
  • MF is the number of methods of the class accessing a particular instance field.
  • Sum(MF) is the sum of MF over all instance fields of the class.

Recommendations: Types where LCOM > 0.8 and NbFields > 10 and NbMethods >10 might be problematic. However, it is very hard to avoid such non-cohesive types. Types where LCOMHS > 1.0 and NbFields > 10 and NbMethods >10 should be avoided. Note that this constraint is stronger (and thus easier to satisfy) than the constraint types where LCOM > 0.8 and NbFields > 10 and NbMethods >10.


NbFields > 10 and NbMethods >10 is highlighted because LCOM / LCOMHS values are significant mostly for large and complex classes.