.NET Linting and Style Tooling

Dated Jul 6, 2025; last modified on Sun, 06 Jul 2025

.NET compiler platform (Roslyn) analyzers are included in the .NET SDK and enabled by default in .NET 5 and later. Code analysis violations are prefixed with CA or IDE to differentiate them from compiler errors.

Not to be confused with CS-prefixed messages that are generated by the C# compiler.

Rule Categories

Rules fall in one of the following categories:

  • Design: Adherence to the design guidelines for .NET libraries .
  • Documentation: Correct use of XML documentation comments for externally visible APIs.
  • Globalization: World-ready libraries and applications.
  • Interoperability: Portability across platforms; interaction with COM clients.
  • Maintainability: Library and application maintenance.
  • Naming: Naming conventions of the .NET design guidelines.
  • Performance: High-performance libraries and applications.
  • SingleFile: Single-file applications.
  • Reliability: Library and application reliability, e.g., thread usage.
  • Security: Prevent security flaws in your program.
  • Style: Consistent code style.
  • Usage: Proper usage of .NET.

Configuration in the MSBuild File

AnalysisMode controls which rules are enabled as build warnings. Possible values are None, Default, Minimum, Recommended, or All (with each being more aggressive than the previous). Can use <AnalysisMode<Category>> to target a specific category of rules, e.g., <AnalysisModeReliability>.

Setting CodeAnalysisTreatWarningsAsErrors to true is equivalent to building with the -warnaserror flag. By default, it’s set to false; you’ll still see code analysis warnings, but they won’t break the build.

Newer versions of .NET may come with more code analysis rules. AnalysisLevel <AnalysisLevel>8.0</AnalysisLevel> locks to the rules that shipped with v8.0 of the .NET SDK. One can also install the Microsoft.CodeAnalysis.NetAnalyzers package to decouple the rule updates from the .NET SDK updates.

Microsoft.CodeAnalysis.NetAnalyzers also comes with predefined .editorconfig files that can be copied to the project’s root directory.

Setting EnforceCodeStyleInBuild to true enables you to enforce consistent code styles at build time. For performance reasons, some rules are exempt from EnforceCodeStyleInBuild and only run in the IDE (e.g., as code refactoring quick actions), e.g., SimplifyNames, RemoveQualification, PreferBuiltInOrFrameworkType, RemoveUnreachableCode, RemoveUnnecessarySuppression, etc. .

Configuration in Config Files

Both code quality and code style rules accept a severity level, e.g.,

# Most specific rule wins. CA1822 will have an effective severity of "error"
dotnet_diagnostic.CA1822.severity = error

# All other rules in the "Performance" category that are enabled by default will
# have a "warning" severity.
dotnet_analyzer_diagnostic.category-performance.severity = warning

# All other rules outside of "Performance" category that are enabled by default
# will have a "suggestion" severity.
dotnet_analyzer_diagnostic.severity = suggestion

… where the severity can be one of none, silent, suggestion, warning, error, or default.

However, if you enable any <AnalysisMode> or <AnalysisLevel>, then any bulk dotnet_analyzer_diagnostic options are ignored. It’s better to enable a category of rules by setting <AnalysisMode<Category>> to All.

.editorconfig files may contain both editor settings (e.g., indent_style = space) and options for code analysis rules. The files apply to source files the current folder, including subfolders, e.g.,

[*.cs]
# Applies to all .cs files in the current folder and subfolders.
dotnet_diagnostic.CA1822.severity = error

By default, auto-generated files (as identified by header or extension) are exempt from code analyzer warnings. Additional files and folders can be configured as follows:

[*.MyGenerated.cs]
generated_code = true

Unlike .editorconfig files, .globalconfig files apply to all source files in a project, regardless of their file paths. .globalconfig do not configure editor settings either. The conventional extension is .globalconfig but there is no limitation (non-conventional paths can be added under the <GlobalAnalyzerConfigFiles> node in the .csproj file).

# Top level entry required to mark this as a global AnalyzerConfig file.
# Even in an implicitly referenced `.globalconfig`, include this by convention.
is_global = true

# By default, .globalconfig files have a level of 100 and others default to 0.
# In case of conflicts, the file with the higher value wins; if there's a tie,
# a compiler warning is reported and conflicting entries are ignored.
global_level = 100

# NOTE: No section headers for configuration entries

#### .NET Coding Conventions ####
# this. and Me. preferences
dotnet_style_qualification_for_method = true:warning
#### Diagnostic configuration ####
# CA1000: Do not declare static members on generic types
dotnet_diagnostic.CA1000.severity = warning

.globalconfig files can be conditionally included to disable/enable certain code analysis rules in different environments, e.g.,

<ItemGroup Condition="'$(IsShipping)' == 'false'">
  <GlobalAnalyzerConfigFiles
    Include="$(MSBuildThisFileDirectory)CodeAnalysis.test.globalconfig" />
</ItemGroup>

Beyond configuring severity, code quality analyzers can be configured to only apply to specific parts of the codebase, e.g.,

# Only analyze public API surfaces
dotnet_code_quality.api_surface = public

# For rules in the Naming category, only analyze internal and private protected APIs.
dotnet_code_quality.Naming.api_surface = friend

… where configurable options include api_surface, allowed_surfaces, excluded_symbol_names, etc.

Code-style rules also have associated options, e.g.,

dotnet_sort_system_directives_first = false
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
dotnet_style_prefer_collection_expression = when_types_loosely_match
csharp_style_var_when_type_is_apparent = false

Configuration in Source Files

One can use preprocessor directives to suppress warnings for specific lines of code, e.g.,

    try { ... }
    catch (Exception e)
    {
#pragma warning disable CA2200 // Rethrow to preserve stack details
        throw e;
#pragma warning restore CA2200 // Rethrow to preserve stack details
    }

For compiler-generated code that doesn’t map to explicitly provided user source, one may use the SuppressMessage attribute in the GlobalSuppressions.cs for the project, e.g.,

[assembly: SuppressMessage(
  "Usage",
  "CA2200:Rethrow to preserve stack details",
  Justification = "Not production code.",
  Scope = "member",
  // Target property accepts the documentation ID for the API being suppressed.
  Target = "~M:MyApp.Program.IgnorableCharacters")]

I don’t fully follow this example. Why would generated code be running into code analyzer errors? Shouldn’t we have:

[*.MyGenerated.cs]
generated_code = true

Or maybe the use-case is for when I’m the one writing the generator, and I don’t want the generated code to be bug-prone?

To get rules like JSON001, JSON002 and RE0001 to kick in, annotate strings that should be identified as JSON or RegEx, e.g.,

// lang=json,strict
var v = """{ "pie": true, "cherry": [1, 2, 3 }""";

// lang=regex,strict
string pattern = @"\b[M]\w+\";

References

  1. Code analysis in .NET | Microsoft Learn. learn.microsoft.com . Accessed Jul 6, 2025.
  2. Configure code analysis rules - .NET | Microsoft Learn. learn.microsoft.com . Accessed Jul 6, 2025.
  3. Configuration files for code analysis rules - .NET | Microsoft Learn. learn.microsoft.com . Accessed Jul 6, 2025.
  4. Suppress code analysis warnings - .NET | Microsoft Learn. learn.microsoft.com . Accessed Jul 6, 2025.
  5. Code quality rule configuration options - .NET | Microsoft Learn. learn.microsoft.com . Accessed Jul 6, 2025.
  6. Predefined configuration files (code analysis) - .NET | Microsoft Learn. learn.microsoft.com . Accessed Jul 6, 2025.
  7. .NET code style rule options - .NET | Microsoft Learn. learn.microsoft.com . Accessed Jul 6, 2025.
  8. Code analysis rule categories - .NET | Microsoft Learn. learn.microsoft.com . Accessed Jul 6, 2025.
  9. roslyn/src/Analyzers/Core/Analyzers/EnforceOnBuildValues.cs at 9f87b444da9c48a4d492b19f8337339056bf2b95 ยท dotnet/roslyn. github.com . Accessed Jul 6, 2025.
  10. Framework Design Guidelines | Microsoft Learn. learn.microsoft.com . Accessed Jul 6, 2025.