C# Clean Code

2026/04/262 min read
bookmark this

Introduction

Even well-written methods become hard to maintain when files and projects are organized inconsistently.

This post covers practical structure rules for teams.

1) Organize class members consistently

A common order:

  1. constants / static readonly fields
  2. private fields
  3. constructors
  4. public properties
  5. public methods
  6. private methods

Consistency reduces navigation time and review friction.

2) Keep related logic close together

Private helper methods should appear near the public method that uses them.

Avoid scattering related logic across long files.

3) One class per file (most of the time)

Use file names that match class names.

  • OrderService.cs -> OrderService
  • OrderNotFoundException.cs -> OrderNotFoundException

Exception: tiny related types such as a request record near a small service.

4) Avoid overusing regions

If a class requires many #region blocks to be readable, the class is likely too large.

Refactor by extracting smaller cohesive classes.

5) Keep project boundaries clear

A clean architecture baseline:

  • Domain: entities, value objects, domain rules
  • Application: use cases, DTOs, interfaces, validators
  • Infrastructure: databases, external APIs, file storage
  • WebApi: controllers, middleware, composition root

This separation makes ownership and dependencies explicit.

6) Comments: explain why, not what

Bad comment

// Check if user is admin
if (user.Role == Role.Admin)
{
    // ...
}

Better code and better comment style

if (user.IsAdmin)
{
    // Discount capped at 30% due to compliance policy REG-2024-117
    discount = Math.Min(discount, 0.30m);
}

Comment only when context or business rule is not obvious.

7) Document public APIs with XML comments

/// <summary>
/// Retrieves an order by its unique identifier.
/// </summary>
/// <param name="id">The order ID.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>The order, or null if not found.</returns>
public Task<Order?> GetByIdAsync(int id, CancellationToken ct);

8) Delete commented-out code

Version control already preserves history. Dead commented blocks make files noisy and misleading.

Summary

Code organization and documentation are force multipliers. Clear structure plus intentional comments makes large C# codebases easier to evolve safely.