Skip to main content

dotnet format & Linting

This document explains dotnet format, a tool for maintaining code quality in .NET projects, and related concepts of Linting (static analysis).

What is dotnet format?​

dotnet format is a code formatter included in the .NET SDK. It automatically fixes code style based on rules defined in an .editorconfig file.

Key Features​

  • Apply Code Style: Unifies styles such as indentation, newlines, and spacing.
  • Fix Analyzers: Automatically fixes some warnings and errors detected by Roslyn analyzers.
  • Organize Imports: Removes unnecessary using directives and sorts them.

Basic Usage​

Installation​

It is included by default in .NET 6 and later SDKs. For earlier versions, you can install it as a global tool using the following command:

dotnet tool install -g dotnet-format

Commands​

Run the following commands in the project root directory:

# Format all files in the solution or project
dotnet format

# Format specific project files
dotnet format ./src/MyProject.csproj

# Check for style issues but do not fix them (used in CI, etc.)
dotnet format --verify-no-changes

Configuration: .editorconfig​

The behavior of dotnet format is controlled by an .editorconfig file placed in the solution root or similar location.

Example .editorconfig​

# Indicates this is the top-level EditorConfig file
root = true

# Apply to all files
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

# C# file specific settings
[*.cs]
# Indentation settings
csharp_indent_labels = one_less_than_current

# Organize usings
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = false

# Code style (var vs explicit type)
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion

Linting and Roslyn Analyzers​

Linting is the process of statically analyzing source code to detect potential bugs, style violations, and suspicious structures. In .NET, Roslyn Analyzers play this role.

How Roslyn Analyzers Work​

Roslyn (the .NET Compiler Platform) provides APIs to analyze code at compile time. This is used to detect code issues in real-time, displaying them as squiggles in Visual Studio or VS Code, or outputting them as build warnings.

dotnet format can be seen as a tool that executes the "Code Fix" features provided by these analyzers in bulk from the command line.

Common Analyzer Packages​

  • Microsoft.CodeAnalysis.NetAnalyzers: A set of recommended analyzers included by default in the .NET SDK.
  • StyleCop.Analyzers: A strict rule set specialized for code style.
  • SonarAnalyzer.CSharp: An analyzer containing SonarQube's rule set.

Local Development Best Practices (Shift Left)​

Detecting errors in CI is the last line of defense, but the feedback loop tends to be slow. A "Shift Left" approach, where developers fix issues while coding or before committing, is recommended.

1. IDE Configuration (Format on Save)​

The easiest and most effective way is to apply formatting the moment a file is saved.

  • VS Code: Add the following to .vscode/settings.json:

    {
    "editor.formatOnSave": true
    }

    Also, by installing the C# Dev Kit extension, you can see Roslyn analyzer warnings in real-time in the editor.

  • Visual Studio: Check "Run Code Cleanup on Save" in [Tools] > [Options] > [Text Editor] > [Code Cleanup]. You can configure a profile to select which rules to apply (such as organizing usings).

2. Leveraging Git Hooks (Husky)​

By automatically running dotnet format before committing and forcing only fixed files to be committed, you can prevent unformatted code from entering the repository.

If you have a Node.js environment, combining Husky and lint-staged is common.

Setup Example:

  1. Install packages

    npm install --save-dev husky lint-staged
    npx husky install
  2. Configure package.json

    {
    "lint-staged": {
    "*.cs": "dotnet format --include"
    }
    }
  3. Create pre-commit hook

    npx husky add .husky/pre-commit "npx lint-staged"

This runs dotnet format only on changed .cs files during git commit.

3. Using Task Runners​

It is convenient to make it easy to run manually using features like VS Code Tasks.

.vscode/tasks.json:

{
"version": "2.0.0",
"tasks": [
{
"label": "dotnet format",
"command": "dotnet",
"type": "process",
"args": ["format"],
"problemMatcher": "$msCompile"
}
]
}

CI/CD Integration​

By using dotnet format in CI/CD pipelines like GitHub Actions, you can maintain the quality of your codebase.

GitHub Actions Example​

Here is an example workflow that checks if the formatting is correct during a pull request.

name: Lint Code

on: [push, pull_request]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'

- name: Verify formatting
run: dotnet format --verify-no-changes --verbosity diagnostic

Using the --verify-no-changes option causes the command to fail (non-zero exit code) if there are files that need formatting, thus failing the CI.

Usage in VS Code​

In VS Code, the C# extension (C# Dev Kit) recognizes .editorconfig and warns about style violations in real-time in the editor.

  • Format on Save: Setting "editor.formatOnSave": true in settings.json automatically applies formatting when saving a file.
  • Quick Fix: Pressing Ctrl + . where a squiggle appears displays suggested fixes that can be applied.

Summary​

  • dotnet format is a powerful CLI tool for unifying code style.
  • Use .editorconfig to share and manage rules across the team.
  • Combining with Roslyn Analyzers helps prevent potential bugs as well as style issues.
  • Integrate into CI/CD to continuously maintain code quality.