Home » Use code analyzers in C# to improve code quality

Use code analyzers in C# to improve code quality

There is a new feature available in Visual Studio 2015 and roslyn compiler – live code analyzers. Those can be used, to improve your code quality. Code analyzers can be installed via NuGet packages and if you want, you can also implement your own analyzers.

What are live code analyzers?

Analyzers are extensions that can be added to the Visual Studio project. They are available in Visual Studio 2015 with the Roslyn compiler and they analyze the code live and check if there are improvements. Live in that case means, that it finds issues as you type. Really cool feature!

Which analyzers are available and how do I get them?

Easiest way to find them is to search for “analyzers” in the NuGet package manager. There are several analyzers available, the most interesting ones in my opinion are:

  • Microsoft.AnalyzerPowerPack
  • Microsoft.CodeAnalysis.FxCopAnalyzers
  • codecracker.CSharp
  • SonarAnalyzer.CSharp
  • StyleCop.Analyzers
  • Microsoft.VisualStudio.Azure.CodeAnalysis (for Azure projects)

So let’s try to use them for one of my previous samples (Get Azure Active Directory groups via Graph API)

How to use analyzers in your project

At first we need to open the NuGet package manager and find the right code analyzer for us. The project that I use is an Azure project, so let’s use the preview of the Microsoft.VisualStudio.Azure.CodeAnalysis (ensure to check the “include prerelease” in the package manager).

codeanalyzer

After installing, we can open our error window to see if there are any issues. Seems that there are 4 of them! The code analyzer also suggests how to fix it. So let’s open the quick actions with Ctrl+. (dot) and let’s replace the code with the correct one:

screenshot warnings

There are only these 4 warnings, so it seems that the Azure specific part is okay. But what about the other things in the code? So let’s add another code analyzer to our project. I’ll use SonarAnalyzer.CSharp in that case.

SonarAnalyzer

We can check the rules that are there in the solution explorer by expanding the References and then the Analyzers:

Screenshot references

Additionally, we can configure the ruleset that we want to use. Just click with right mouse on “Analyzers” and select “Open Active Rule Set”

screenshot open active rulesets

Now we can select the rules that we want to use in our solution.

Screenshot active code rules

If you modified them and you want to reset the rules to default rules, then you can delete the .rulesettings file that was created automatically when you modified them.

Which analyzers are the right ones for me?

You will hate the answer, but: it depends! There are some specific code analyzers – e.g. Microsoft.VisualStudio.Azure.CodeAnalysis for Azure projects or AsyncUsageAnalyzers with best practices for writing asynchronous code. Search for them and check if there is one that fits to your project.

It’s the same for the generic analyzers, but to make the decision easier, check the table below.

Comparison of C#/.net code analyzers

The first question for me was: how much rules do the different analyzers contain?

Name Rules Errors Warnings Info None Hidden
Microsoft.AnalyzerPowerPack 13 0 8 0 5 0
Microsoft.CodeAnalysis.FxCopAnalyzers 132 0 85 0 47 0
CodeCracker.CSharp 76 5 28 23 1 19
SonarAnalyzer.CSharp 174 0 110 6 39 19
StyleCop.Analyzers 171 0 163 0 8 0
Microsoft.VisualStudio.Azure.CodeAnalysis 13 1 12 0 0 0

The table above shows how much rules in total and per level are part of the analyzer. It could be that the number of rules have changed for some of them, depending on the version that you use. I used the packages that were available at the end of August 2016.

It seems that the SonarAnalyzer contains most of the rules, but StyleCop and FxCop are the most popular as they existed before roslyn as code analyzer tools. In my opinion, FxCop has one disadvantage – it uses a lot of other packages and also the rules are splitted into many subrules. Let’s have a look at them:

Microsoft.CodeAnalysis.FxCopAnalyzers

This package installs the following sub packages:

  • Desktop.Analyzers
  • Microsoft.ApiDesignGuidelines.Analyzers
  • Microsoft.Maintainability.Analyzers
  • Microsoft.QualityGuidelines.Analyzers
  • System.Collections.Immutable.Analyzers
  • System.Resources.Analyzers
  • System.Runtime.Analyzers
  • System.Runtime.InteropServices.Analyzers
  • System.Security.Cryptography.Hashing.Algorithms.Analyzers
  • System.Threading.Tasks.Analyzers
  • Text.Analyzers

As a result, the rules are also splitted into the following ones:

Name Rules Errors Warnings Info None Hidden
Desktop.Analyzers 6 0 6 0 0 0
Desktop.CSharp.Analyzers 13 0 4 0 9 0
Microsoft.ApiDesignGuidelines.Analyzers 53 0 38 0 15 0
Microsoft.ApiDesignGuidelines.CSharp.Analyzers 13 0 4 0 9 0
Microsoft.Maintainability.Analyzers 3 0 3 0 0 0
Microsoft.Maintainability.CSharp.Analyzers 2 0 0 0 2 0
Microsoft.QualityGuidelines.Analyzers 7 0 6 0 1 0
Microsoft.QualityGuidelines.CSharp.Analyzers 3 0 1 0 2 0
System.Collections.Immutable.Analyzers 1 0 1 0 0 0
System.Resources.CSharp.Analyzers 1 0 1 0 0 0
System.Runtime.Analyzers 14 0 12 0 2 0
System.Runtime.CSharp.Analyzers 7 0 3 0 4 0
System.Runtime.InteropServices.Analyzers 2 0 2 0 0 0
System.Runtime.InteropServices.CSharp.Analyzers 3 0 1 0 2 0
System.Security.Cryptography.Hashing.Algorithms.CSharp.Analyzers 2 0 2 0 0 0
System.Threading.Tasks.Analyzers 1 0 1 0 0 0
Text.CSharp.Analyzers 1 0 0 0 1 0

I like it simple and easy and I lose track of my rules and packages if there are that much – just for some analyzers. That’s why I would not use FxCop analyzers.

What about the others?
The other mentioned analyzers install only one NuGet package which makes it much easier to maintain it and to remove it if you want to switch to another code analyzer. Simple and clean! So let’s check the others:

Microsoft.AnalyzerPowerPack

The Microsoft AnalyzerPowerPack contains only 13 rules and those are splitted into Common and CSharp:

Name Rules Errors Warnings Info None Hidden
Microsoft.AnalyzerPowerPack.Common 8 0 5 0 3 0
Microsoft.AnalyzerPowerPack.CSharp 5 0 3 0 2 0

The rules are useful, but most of them are also included in codecracker, SonarAnalyzer or StyleCop. That’s why I would go for one of those three:

CodeCracker, SonarAnalyzer and StyleCop

At the first glimpse those three look similar. SonarAnalyzer has 174 rules, StyleCop 171 and CodeCracker has 76. The SonarAnalyzer has most of the rules and should therefore be the number 1. But what’s more important is the quality of the rules. To check that, I downloaded a popular solution from GitHub, added all 3 code analyzers to the solution and ran the code analysis with the following result:

Analyzer Total messages Warnings Info Unique rules *
CodeCracker 1014 961 65 20
SonarAnalyzer 706 706 0 33
StyleCop 31042 31042 0 83

* Unique rules is the number of rules that matched at least once.

StyleCop has most of the messages because it also tells you to add file headers, add blanks after an if statement, enable xml documentation output and such things. If you have an existing project, then it will be a lot of work to fix all the warnings and I see this as a problem. As long as you have only 10 warnings, the developers will try to reduce them to 0, but if there are already 31042 warnings – who cares if there are 100 more?
So I would only use it in very restricted projects and if so, I would add it at the beginning so that warnings will be fixed during development. Another possibility is to use the StyleCop and suppress all messages that aren’t important for you. It takes some time to configure it, but it helps that all developers use the same coding standard. I would do that only for big projects or product development.

CodeCracker and SonarAnalyzer are both very good. CodeCracker usually shows a bit more warnings when you add them, but it also contains some rules that I personally don’t like – e.g. it suggests to use var instead of the typename. In my opinion both options – using var and using the typename is okay.
Both analyzers focus more on a clean code (e.g. make variable constant, handle exception or explain why it can be ignored, verify if delegate is null before invoking it, …) and not that much on the coding standard itself (e.g. method should start with uppercase).

Conclusion

Microsoft.CodeAnalysis.FxCopAnalyzers contains good rules, but there too much dependent NuGet packages and it’s hard to have a good overview of it. It’s also not that easy to maintain the packages and updated them.

Microsoft.AnalyzerPowerPack contains only 13 rules and most of them are part of one of the other analyzers. You can add them because it’s easy to remove them (no dependent package), but in my opinion you don’t really need it, if you have one of the following three.

StyleCop.Analyzers contains a lot of rules, especially for code formatting. This results in a lot of warnings when you add this analyzer. It is very good if you want to force the development to keep to a coding standard, but it will require a lot of changes in the code or to configure the rules and active them step by step. Otherwise it will be frustrating if there are tons of warnings and no one would care about it. I personally like StyleCop and already used it in some projects.

codecracker.CSharp and SonarAnalyzer.CSharp are my personal winners. They contain useful rules, but not too much. They focus more on the code quality and they are easy to install and uninstall. If I compare codecracker and sonaranalyzer, I personally would use the SonarAnalyzer because it is more frequently updated (last updated: 29.08.2016, 27.07.2016, 28.06.2016 vs. 03.04.2016 for codecracker) and it works together with sonarqube. There are some rules that both of them contain, but there are also a lot of different rules. It’s no problem to use both of them if you don’t want to choose one of them.

Side information

Difference between None and Hidden

There are the levels none and hidden for the rules and you probably asked yourself: What is the difference between those two? According to https://github.com/dotnet/roslyn/blob/master/docs/compilers/Rule%20Set%20Format.md, the difference between Hidden and None is, that the analysis is still performed when the action is set to hidden. It would be possible to create custom UI to show them. None means that the rule is disabled.

Default ruleset (without configuring anything)

A C# project has a default ruleset with the following number of rules (default configuration):

Name Rules Errors Warnings Info None Hidden
Managed Binary Analysis 232 0 62 0 170 0
Microsoft.CodeAnalysis.CSharp 165 0 162 1 0 2
Microsoft.CodeAnalysis.CSharp.EditorFeatures 2 0 0 0 0 2
Microsoft.CodeAnalysis.CSharp.Features 6 0 0 0 0 6

Additional information

Getting started with roslyn analyzers: https://msdn.microsoft.com/en-us/library/mt162308.aspx

Improve Your Code Quality using Live Code Analyzers: https://dotnetvibes.com/2016/01/30/improve-your-code-quality-using-live-code-analyzers/

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *