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.