Clean Code in C#: Principles of Writing Readable Code with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Clean Code is the Key to a Successful Project?



In the world of software development on the .NET platform, writing working code is only half the battle. True mastery is demonstrated in the ability to create code that is easy to read, maintain, and extend. The concept of Clean Code, popularized by Robert C. Martin, is a set of principles that transform a chaotic program into a coherent, understandable system. For a C# developer, following these principles means not only respect for colleagues but also a significant reduction in time spent on debugging and implementing new features.



In this article, we will break down the key principles of Clean Code as applied to the C# language and the .NET framework. You will see specific examples of "bad" and "good" code that will help you write higher quality applications.



Principle 1: Meaningful Names and Consistent Style



Proper Naming of Variables and Methods

The name of a variable, class, or method should answer the questions: "What is this?" or "What does it do?". Avoid single-letter abbreviations (except for loop counters) and abstract names like data, info, temp.



Bad example:

public int Calc(int a, int b) // What are a and b? What does the method do?{    int d = a * b;    return d;}


Good example (Clean Code):

/// <summary>/// Calculates the area of a rectangle./// </summary>public int CalculateRectangleArea(int width, int height){    int area = width * height;    return area;}


Consistency within the Team

Use camelCase for local variables and parameters, PascalCase for methods and classes, _camelCase for private fields (according to popular .NET guidelines). This makes the code predictable.



public class OrderService{    private readonly IOrderRepository _orderRepository; // private field

public async Task<Order> GetOrderByIdAsync(int orderId) // method { var order = await _orderRepository.FindAsync(orderId); // local variable return order; }}


Principle 2: Small Functions and the Single Responsibility Principle (SRP)



A Function Should Do Only One Thing

This is the most important principle of Clean Code. If a method performs several actions (validation, logging, business logic, saving to the database), it is difficult to test and modify. Break such methods down into smaller ones.



Bad example (method does everything at once):

public void ProcessOrder(Order order){    // 1. Validation    if (order == null || order.TotalAmount <= 0)        throw new ArgumentException("Invalid order");

// 2. Logging Console.WriteLine($"Processing order {order.Id}");

// 3. Business logic var discount = order.TotalAmount > 100 ? 0.1m : 0; order.FinalAmount = order.TotalAmount - (order.TotalAmount * discount);

// 4. Saving _context.Orders.Add(order); _context.SaveChanges();}


Good example (separation into methods):

public void ProcessOrder(Order order){    ValidateOrder(order);    LogOrderProcessing(order);    ApplyDiscount(order);    SaveOrder(order);}

private void ValidateOrder(Order order){ if (order == null || order.TotalAmount <= 0) throw new ArgumentException("Invalid order", nameof(order));}

private void LogOrderProcessing(Order order){ Console.WriteLine($"Processing order {order.Id}");}

private void ApplyDiscount(Order order){ const decimal discountThreshold = 100m; const decimal discountRate = 0.1m;

if (order.TotalAmount > discountThreshold) { order.FinalAmount = order.TotalAmount - (order.TotalAmount * discountRate); }}

Blogs

Book Recommendations