StudioTools > Code Metrics

This view adds a variety of commonly used code metrics to Visual Studio. By sorting and filter you can find problem areas in your code such as overly complex classes or methods with too many parameters.

Viewing solution metrics

The Code Metrics view is accessed through the StudioTools menu. Click the refresh button in the Code Metrics toolbar to calculate metrics for your solution. This will essentially do a debug build and analyze the compiled projects.

The report shows each method in your solution and the various metrics for each one. You can click to navigate to any of the displayed metrics For most metrics, an aggregate or average value is shown at the type, namespace, and assembly level. Some metrics (like number of parameters) only make sense at the method level however. The various metrics and their behaviors are described in the text that follows.

Sorting

As you might expect, you can click on any column to sort by that metric. For instance, you can find the least maintainable code by clicking on the Maintainability column to sort the worst methods to the top. Note that sorting happens at each level of the hierarchy, as well as within. Click again to reverse the sort order.

Filtering

You can use the filter bar to select which namespaces and assemblies you want to include in your metrics report. Just click on the filter bar, then check (or uncheck) the appropriate items. These will be remembered between runs. For instance, you may not want to included your unit test assemblies or third party code in your report.

Grouping

Similarly you can use the grouping functions on the tool bar to group the displayed results by assembly, namespace, type, or any combination of the above. If you turn off all of the grouping you will see only methods.

Export to XML

The export to XML button will save off your currently displayed metrics to an XML file. You can use this to generate reports or track progress over time. If you are using the filtering function, this will effect the output of the report.

The Metrics

The following metrics are visible through Code Metrics. You can right click in the Code Metrics window to select which ones are shown.

Coupling

Coupling indicates the distinct number of dependencies a an element has on other types. Coupling is thus a measure of how stand alone a program element can be. Coupling excludes primitives types such as int, string, and object.

For methods, this counts the distinct number of types a method uses in its code body, including parameters, return value, variables, and calls.

For types, this counts the distinct number of types used in all constituent methods, as well as the distinct types used in fields.

Rolling up from types to namespaces, and then to assemblies is a combined distinct count of all types and methods used. This is different than a sum to avoid double counting.

Cyclomatic Complexity

Cyclomatic complexity represents the number of paths possible through code by looking at branches and conditions. More paths indicates a larger test surface and makes code harder to understand.

This is computed by looking to the emitted MSIL instructions and counting the number of different branch and jump instructions including conditionals, breaks, returns, and paths through exception handlers. There is always at least one path through the code for any method with a body, and additional branches and conditions add more paths.

This method of counting analyzes your code based on the actual generated assembly, not just your source and so gives you a more thorough scoring of how the complex the code is to the .NET runtime.

Types, namespaces, and assemblies average the complexity of their constituent methods.

Executable Lines of Code (LoC)

Executable lines of code are computed by reading your compiled assemblies and .pdb debug files to find those lines that .NET considers to be real, executable code.

This is a more accurate metric than simply source lines, as it tells you what is going to run. At first glance however, some counts may not appear correct because what looks like several lines to us is really a single executable statement by the time the compiler sees it.

Number of Parameters

Number of parameters for a method, not including the return value. A large number of parameters makes methods difficult to use and encourages errors via passing nulls in place of proper parameter values.

Inheritance Depth

Inheritance depth counts how deep a type is within the inheritance tree All objects initially inherit from System.Object, which is defined to have a depth of 0. Each use of inheritance into a new sub type increments this depth by one.

Deep inheritance trees can lead to complex code that requires understanding multiple base types in multiple files to understand and work with a type.

Depth of inheritance is defined only one types, not methods, namespaces, or assemblies.

Number of Instructions

Number of instructions counts the amount of MSIL generated for your methods. NOP instructions are excluded from the count.

Instructions are the fundamental unit of processing for the .NET runtime. Large numbers of instructions in a method take longer to run through the JIT compiler and increase the size of your assembly on disk and in memory.

Maintainability Index

Maintainability combines line count, complexity, and code volume to provide a synthetic score between 0 and 100 that indicates how easy code is to maintain.

Maintainability uses Halstead metrics, which require the definition of operators and operands. Operators are defined to be any MSIL instruction except nop. Call instructions count the target method as the operator, and contribute the target method's type as an operand. New object instructions count the target type as an operator and an operand. Operands are defined to be any type used in a field, parameter, or variable.

For namespaces and assemblies, the average complexity, volume, and lines of code are used to roll up maintainability. The formula for maintainability is logarithmic, so don't expect the numbers to add up like sums.

You can think of the score as a percentage grade, numbers closer to 100 are better.

Number of Variables

Number of variables counts the variables used in your methods and fields used in your types.

Type level variables use sums all method variables with the fields in the type.

Large numbers of variables make methods more complex and testing more difficult as the total number of potential state combinations increases with each variable.