Visual Studio Code Metrics
Judging the maintainability of an application's source code objectively during code reviews can be difficult. To help, some Visual Studio editions can calculate code metrics, such as cyclomatic complexity, depth of inheritance and lines of code.
There are various metrics that can be calculated for source code. These can help to determine its complexity, readability or maintainability. When you are involved in code reviews, it can be useful to determine such metrics for the code being examined. This can help you to identify problem areas and rectify issues before they become too embedded in the software.
Visual Studio 2008 introduced a set of five automatically calculated metrics, which continued to be present in Visual Studio 2010 and 2012. Unfortunately they are not available in all editions of the integrated development environment (IDE). Visual Studio 2008 users require one of the Team System editions. Users of later versions must have either the Premium or Ultimate editions in order to generate metrics.
The five available metrics are:
- Maintainability Index
- Cyclomatic Complexity
- Depth of Inheritance
- Class Coupling
- Lines of Code
The following sections describe each of these metrics, before explaining how you can generate them.
The maintainability index gives an indication of how easy it should be to understand and modify the code. The index gives a value between zero and one hundred with lower numbers indicating code that may be more difficult to work with.
This metric is the only one that is also presented graphically within the IDE. A value below ten is shown with a red icon. If you have code with such a low maintainability index you should investigate it and rectify the problems as soon as possible. A yellow icon, indicating a maintainability index between ten and nineteen also indicates code that requires attention.
When the index is twenty or more, the icon turns green. This is quite a low cut-off for an indicator that many people would assume means good maintainability. In general you should aim for a much greater value than twenty.
The maintainability index is based upon several other values. They include the cyclomatic complexity and lines of code metrics, which we'll see in a moment. The index also considers the Halstead Volume, described by Maurice Howard Halstead. This is a measure of the computational complexity of algorithms, determined by the number of operands and operators used. Fewer of each leads to better maintainability.
To improve the maintainability index for some source code you can reduce the number and complexity of operations in each unit of code, lower the cyclomatic complexity or decrease the number of lines of code.
The cyclomatic complexity is a measure of structural complexity. It is related to the number of possible routes through a unit of code. A simple method with no branching cause by if or switch statements will have a very low cyclomatic complexity. Each additional conditional processing command increases the complexity and decreases the code's readability.
The actual value for cyclomatic complexity varies according to the version of Visual Studio used to calculate it. Visual Studio 2010 and later versions increase the value when encountering catch statements. Visual Studio 2008 does not.
A rule of thumb is that no individual method or property should have a cyclomatic complexity that is greater than ten. Lower numbers are preferred but higher values can be acceptable in some cases. This rule does not apply to classes or structures, as their complexity is derived from the total complexity of their contained members.
To reduce the cyclomatic complexity you should consider refactoring to extract methods. This may change a single method with a value of ten into two methods, each with lower complexity. If a method has a high value due to a large set of switch cases you might consider refactoring the code to use a design pattern, such as the Strategy pattern.
Depth of Inheritance
Depth of inheritance describes the number of classes from which a specific type inherits functionality. The idea is that if more types exist in an inheritance hierarchy, the code will likely be more difficult to maintain as a result. However, a high depth of inheritance can also indicate a greater level of code reuse. This means that it is difficult to say what a good depth is.
Microsoft does include a code analysis rule (CA1501), which generates a warning when an inheritance hierarchy is more than four levels deep. However, the documentation for this rule says that it is acceptable to ignore the warning. It's also worthy of note that many .NET framework classes, some of which you may decide to subclass, have a larger depth of inheritance.
13 April 2013