Raising Coding Standards with .NET 6.0 Code Analyzers
Automated code analysis has been a feature of .NET since its earliest days. It started out with tools that would detect when library components didn't meet the Framework Design Guidelines, but over the years, more and more sophisticated tools have become available.
There was a sea change when Microsoft released Roslyn a few years ago. Roslyn provides an API making it possible for analyzers to get hold of C# compiler's understanding of the source code, and also to make modifications in a reliable way. This made it dramatically easier to write much more sophisticated analyzers. We now have analyzers that can detect common multithreading bugs, and others that look for specific security problems. And it's now not uncommon for a NuGet package to incorporate analyzer that check for common misuses specific that library!
Before .NET 6.0, it could be tricky to ensure that you had the latest versions of all the analyzers you wanted. The long history of analyzers in .NET meant that it wasn't always clear where to look. The first widely used .NET Analyzer, the original tool for Framework Design Guideline compliance, started out as a standalone tool called FxCop. After Roslyn came along, this was superseded by the Microsoft.CodeAnalysis.FxCopAnalyzers
NuGet package, but that package's page now suggests you look at the Microsoft.CodeAnalysis.NetAnalyzers
package instead.
However, if you read the Frequently asked questions about legacy FxCop and .NET analyzers it will tell you that maybe you don't need that. At one point Visual Studio offered its own built-in code analysis features that incorporated some of the same checks, but those eventually started using the Roslyn analyzers instead, although there's still a Visual Studio user interface for them. And although this UI has switched to using the analyzers, the RunCodeAnalysis
msbuild setting still runs the old standalone FxCop tool. And all that just for one particular kind of analysis! Some other popular analyzers started out as Visual Studio extensions, but have turned into NuGet packages (e.g., Roslynator).
With this history it can be hard to work out what to do, particularly when a lot of the advice you might find by searching the internet may no longer be applicable.
.NET SDK 6.0 simplifies things
With .NET SDK 6.0, Microsoft's code analyzers are built in, and switched on by default. (In fact, this started with the 5.0 SDK, and analysis is on by default for projects targetting .NET 5.0 or later.) So you don't need to add any references to anything get access to the code analysis that has previously been done by FxCop.
Volume control
Only a few of analyzer rules are enabled by default. This set is pretty conservative—just 16 warnings in fact. You can crank the level up a little by adding the AnalysisMode
setting to your .csproj
files:
<PropertyGroup>
<AnalysisMode>Recommended</AnalysisMode>
</PropertyGroup>
Or you can go for the full firehose (over 200 different warning types) by turning on everything:
<PropertyGroup>
<AnalysisMode>All</AnalysisMode>
</PropertyGroup>
Alternatively, you can choose which particular kinds of analysis you're most interested in. Perhaps you are writing an application that will never need to be localized, and so you don't care to see any warnings for that, but you do want to see all available security analysis warnings, and want to stick with the recommended levels for everything else, in which case you could write this:
<PropertyGroup>
<AnalysisMode>Recommended</AnalysisMode>
<AnalysisModeGlobalization>None</AnalysisModeGlobalization>
<AnalysisModeSecurity>All</AnalysisModeSecurity>
</PropertyGroup>
There are 12 categories in this AnalysisMode<Category>
form: Design
, Documentation
, Globalization
, Interoperability
, Maintainability
, Naming
, Performance
, SingleFile
, Reliability
, Security
, Style
, and Usage
.
Easing into new .NET versions
The recommended analyzers change with each release of .NET, and you might decide that you want to upgrade to a newer .NET runtime without immediately having to fix all the new analyzer warnings. For this, you can configure analysis with the AnalysisLevel
setting instead. For example, the following setting will give you the same analyzers as you would have had building for .NET 5.0 with <AnalysisMode>Recommended</AnalysisMode>
even when targetting new runtimes:
<PropertyGroup>
<AnalysisLevel>5.0-recommended</AnalysisLevel>
</PropertyGroup>
Controlling individual rules
Up until VS2019 v16.5, you could configure the settings for individual analyzer warnings by adding a "ruleset" file. However, this approach has been deprecated in favour of putting rules into the .editorconfig
file (which is also where code style settings live). For example, you can disable the rule that insists that all string constants must be localized with this setting:
dotnet_diagnostic.CA1303.severity = None
You could also manage this by setting the NoWarn
build property, but that simply disables the warnings entirely. With .editorconfig
you can select other levels. For example instead of None
you could set it to Silent
, at which point it will no longer appear in Visual Studio's Error List panel, but the analyzer will still run, and IDE will still offer a lightbulb suggestion to change the code if you inspect the line in question.
This integration of analyzers into the the SDK is part of the increasing maturity of the tool chain with .NET 6.0—instead of having to cobble together references to a fragmented set of tools, this fundamental technique for improving the quality of your code is now built right into the standard tools.