← Back

Coding Styles in Visual Studio with .editorconfig

2026-01-13 18:08 · 👁 29503

#c#

Coding Styles in Visual Studio with .editorconfig (including async naming)

Coding style debates are endless… until you put them in code.

With EditorConfig, you can standardize formatting + C# style rules across:

  • Visual Studio / Rider / VS Code
  • every developer machine
  • CI builds
  • your whole repo

Result: fewer PR comments, fewer formatting diffs, more consistent code.


What is .editorconfig?

.editorconfig is a plain text file that defines coding conventions per folder/file pattern.

Visual Studio reads it automatically and can:

  • format code accordingly
  • show suggestions/warnings/errors in the editor
  • auto-fix many issues (Code Cleanup / Fix All)

Put it at the repo root:

/.editorconfig
/src/...

Create it in Visual Studio (fast)

  1. Right click your project/solution
  2. Add > New Item
  3. Search for EditorConfig
  4. Choose:
    • .editorconfig file (default)
    • or .editorconfig for .NET (comes with common C# rules)

Tip: VS can also generate it from current settings.


A solid “starter” .editorconfig for C# teams

This is a pragmatic baseline: consistent formatting + readable style + a few high-signal rules.

root = true

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

# C# files
[*.cs]
# --- Formatting ---
csharp_new_line_before_open_brace = all
csharp_indent_case_contents = true
csharp_indent_switch_labels = true

# --- "var" preferences ---
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = false:suggestion

# --- Modern C# ---
csharp_style_expression_bodied_methods = when_on_single_line:suggestion
csharp_style_prefer_switch_expression = true:suggestion
csharp_style_prefer_pattern_matching = true:suggestion

# --- Using directives ---
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = true

# --- Qualification ---
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion

# --- Braces ---
csharp_prefer_braces = true:warning

# --- Unused / unnecessary ---
dotnet_style_readonly_field = true:suggestion
dotnet_diagnostic.IDE0005.severity = warning   # Remove unnecessary usings

The 3 levels of enforcement: suggestion vs warning vs error

You can decide how strict your team is:

  • :suggestion → hints (great for gradual adoption)
  • :warning → visible and actionable (best default for teams)
  • :error → enforce in CI for “must comply” rules

Example:

csharp_prefer_braces = true:warning

Enforce async naming: every async method ends with Async

A convention that saves real time:

  • SaveAsync(), GetUserAsync()
  • Save(), GetUser() (but returns Task) ❌

This makes APIs predictable and avoids “surprise async” at call sites.

.editorconfig naming rule (async suffix)

This rule targets methods that:

  • are marked async
  • return Task, Task<T>, ValueTask, or ValueTask<T>
  • and must end in Async
# Enforce: async methods must end with "Async"
dotnet_naming_rule.async_methods_end_with_async.severity = warning
dotnet_naming_rule.async_methods_end_with_async.symbols = async_methods
dotnet_naming_rule.async_methods_end_with_async.style = end_with_async

dotnet_naming_symbols.async_methods.applicable_kinds = method
dotnet_naming_symbols.async_methods.applicable_accessibilities = public, internal, protected, private
dotnet_naming_symbols.async_methods.required_modifiers = async
dotnet_naming_symbols.async_methods.required_return_types = System.Threading.Tasks.Task, System.Threading.Tasks.Task`1, System.Threading.Tasks.ValueTask, System.Threading.Tasks.ValueTask`1

dotnet_naming_style.end_with_async.required_suffix = Async
dotnet_naming_style.end_with_async.capitalization = pascal_case

✅ Allowed:

public async Task SaveAsync() { }
public async ValueTask<int> ComputeAsync() => 42;

❌ Warns:

public async Task Save() { }
private async Task<int> Compute() => 42;

Note: this enforces by signature (async + task-like return). If you also want to enforce Async for methods that return Task but aren’t marked async (wrappers), you can add a second rule.


Naming rules: one more example (private fields)

Naming rules scale well because they remove subjective reviews.

dotnet_naming_rule.private_fields_should_be_camel_with_underscore.severity = suggestion
dotnet_naming_rule.private_fields_should_be_camel_with_underscore.symbols = private_fields
dotnet_naming_rule.private_fields_should_be_camel_with_underscore.style = camel_underscore

dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private

dotnet_naming_style.camel_underscore.required_prefix = _
dotnet_naming_style.camel_underscore.capitalization = camel_case

Make it enforceable in CI

Formatting and style don’t “stick” unless CI checks them.

Recommended approach:

  1. keep severities in .editorconfig
  2. run formatting in CI
dotnet format --verify-no-changes

This fails the build if someone committed changes that should have been formatted/fixed.


Visual Studio workflow your team will actually use

  1. Code Cleanup profiles

In Visual Studio:

  • Tools > Options > Text Editor > Code Cleanup
  • Create a profile: remove usings, apply formatting, apply code-style fixes

Then devs run:

  • Ctrl+K, Ctrl+E (format document)
  • Code Cleanup (profile)
  1. Fix All

When a rule triggers:

  • lightbulb → Fix all occurrences (document/project/solution)

Perfect for gradually adopting stricter rules.


Safe rules to start with (low drama, high value)

✅ great first wave:

  • remove unused usings
  • require braces
  • whitespace/newline consistency
  • sort/group usings
  • readonly fields suggestions
  • async suffix naming

⏳ later:

  • strict var rules
  • expression-bodied preference
  • big naming conventions across the whole repo (can create huge diffs)

Wrap-up

EditorConfig turns “style preferences” into repeatable engineering.

Your repo becomes consistent, PRs become cleaner, and formatting stops being a human problem.

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.