C# Beautifier
Free online C# code beautifier and formatter. Automatically indent, format braces, and clean up your C# source code with configurable style options.
About
Inconsistent indentation and brace placement in C# codebases cause merge conflicts, obscure logic errors, and slow code reviews. A single misplaced closing brace } after a refactor can silently change control flow without triggering a compiler error. This tool parses your C# source through a state-machine tokenizer that distinguishes code from string literals (@"", $""), comments (//, /* */, ///), and preprocessor directives (#region, #if). It then applies deterministic indentation rules based on brace depth, normalizes blank lines between members, and positions braces according to your chosen convention (Allman or K&R).
The formatter handles edge cases including nested generic type parameters Dictionary<string, List<int>>, lambda expressions, LINQ query syntax, and switch expressions introduced in C# 8.0. It preserves content inside all string literal types and comment blocks verbatim. This tool approximates formatting behavior assuming syntactically valid C# input. Malformed code (unmatched braces, unterminated strings) will be formatted on a best-effort basis with a warning.
Formulas
The beautifier operates as a two-phase pipeline: tokenization followed by reconstruction.
Each token Ti carries a type classification and raw text. The tokenizer is a finite state machine with states: DEFAULT, IN_STRING, IN_VERBATIM_STRING, IN_INTERPOLATED_STRING, IN_RAW_STRING, IN_CHAR, IN_SINGLE_COMMENT, IN_MULTI_COMMENT, IN_PREPROCESSOR. Transitions are character-driven with one-character lookahead.
The formatter walks the token stream maintaining an indent depth counter d. On encountering {, it emits the brace (on current or new line per style), then increments: d ← d + 1. On }, it decrements first: d ← max(0, d − 1), then emits the brace at the new depth. Each new line is prefixed with d × indent characters (spaces or tabs). Consecutive blank lines are collapsed: maximum 1 empty line between blocks.
Where indent = the configured indentation string (e.g., 4 spaces), style ∈ {Allman, K&R} determines whether opening braces appear on a new line or the same line as the controlling statement, and d ≥ 0 is clamped to prevent negative indentation from malformed input.
Reference Data
| C# Feature | Syntax Pattern | Formatter Handling | Since Version |
|---|---|---|---|
| Namespace declaration | namespace X { } | Brace on new line, contents indented | C# 1.0 |
| File-scoped namespace | namespace X; | Semicolon ends line, no brace indent | C# 10 |
| Verbatim string | @"..." | Content preserved, no formatting inside | C# 1.0 |
| Interpolated string | $"...{expr}..." | Content preserved, expressions untouched | C# 6.0 |
| Raw string literal | """...""" | Content preserved verbatim | C# 11 |
| XML doc comment | /// <summary> | Preserved at current indent level | C# 1.0 |
| Multi-line comment | /* ... */ | Content preserved, indent first line only | C# 1.0 |
| Preprocessor directive | #if, #region, #pragma | Placed at column 0 (no indentation) | C# 1.0 |
| Lambda expression | x => x + 1 | Kept inline, multi-line body indented | C# 3.0 |
| LINQ query | from x in y select z | Each clause on new indented line | C# 3.0 |
| Switch expression | x switch { ... } | Arms indented inside braces | C# 8.0 |
| Pattern matching | is { Prop: value } | Braces formatted at expression level | C# 7.0 |
| Record type | record Person(string Name); | Positional params kept inline | C# 9.0 |
| Init-only setter | init; | Formatted as normal property accessor | C# 9.0 |
| Top-level statements | Console.WriteLine(); | Formatted at indent level 0 | C# 9.0 |
| Global using | global using System; | Kept at top, no indentation | C# 10 |
| Attribute | [Serializable] | Own line, aligned with target member | C# 1.0 |
| Generic constraints | where T : class | Indented under declaration | C# 2.0 |
| Async/Await | async Task Method() | Keywords kept inline with signature | C# 5.0 |
| Null-conditional | x?.Property | No whitespace inserted around ?. | C# 6.0 |