Clean Code in C#: Principles and Examples for .NET Developers

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

Clean Code in C#: How to Write Code You Want to Read



Every .NET developer has encountered a situation where their own code becomes unreadable after a month or two. To avoid this, there is the philosophy of Clean Code, popularized by Robert Martin. In this article, we will break down the main principles of clean code in C# with concrete examples that will help you write maintainable and scalable applications.



Why Clean Code is Important for a C# Developer?



Clean code is not just about pretty formatting. It is a set of practices that make code:

  • Readable — any developer can quickly understand the logic;
  • Maintainable — easy to make changes without risking breaking the system;
  • Testable — code is easily covered by unit tests;
  • Efficient — no unnecessary abstractions or duplication.


In C#, with its strong typing and powerful .NET capabilities (LINQ, async/await, Records), following Clean Code principles is especially important. Bad code in C# can lead to non-obvious bugs and performance issues.



Principle 1: Naming Variables and Methods



A variable or method name should answer the question "what is this?" or "what does it do?". Avoid single-letter abbreviations (except for loop indices).



Bad Example

public class Data{    public int a; // what is this?    public string b; // unclear

public void Do(int x, int y) // what does the method do? { var r = x + y; Console.WriteLine(r); }}


Good Example (Clean Code)

public class Customer{    public int Id { get; set; }    public string FullName { get; set; }

public void PrintCustomerSummary(int customerId, int orderCount) { var totalOrders = customerId + orderCount; Console.WriteLine($"Customer {customerId} has {totalOrders} orders"); }}


Rule: Names should be expressive. If a variable is called data, that is almost always bad. Use customerData, orderList, invoiceTotal.



Principle 2: Small Methods with a Single Responsibility



Each method should do exactly one thing. If a method contains more than 10-15 lines, it most likely needs to be broken down. This is the basis of the Single Responsibility principle (from SOLID).



Bad Example (method does everything)

public void ProcessOrder(int orderId){    // 1. Validation    if (orderId <= 0) throw new ArgumentException("Invalid ID");        // 2. Getting data from DB    var order = _db.Orders.Find(orderId);        // 3. Calculating discount    decimal discount = 0;    if (order.Total > 1000) discount = order.Total * 0.1m;        // 4. Sending email    var email = new MailMessage();    email.To.Add(order.CustomerEmail);    email.Subject = "Order processed";        // 5. Logging    _logger.LogInformation("Order {Id} processed", orderId);}


Good Example (refactoring)

public void ProcessOrder(int orderId){    ValidateOrderId(orderId);    var order = GetOrderFromDatabase(orderId);    var discount = CalculateDiscount(order);    SendConfirmationEmail(order, discount);    LogOrderProcessing(orderId);}

private void ValidateOrderId(int orderId){ if (orderId <= 0) throw new ArgumentException("Order ID must be positive", nameof(orderId));}

private Order GetOrderFromDatabase(int orderId){ return _db.Orders.Find(orderId) ?? throw new InvalidOperationException("Order not found");}

private decimal CalculateDiscount(Order order){ return order.Total > 1000 ? order.Total * 0.1m : 0;}

private void SendConfir

Blogs

Book Recommendations