What is the Clean Code?
Clean code is code that is simple, easy to read, and easy to maintain. It follows certain rules that make it understandable, scalable, and flexible. Writing clean code reduces the chances of bugs and avoids technical problems that can make the code harder to manage later on.
Best Practices for Writing Clean Code in .NET
1. Follow the SOLID Principles
SOLID principles are five important rules that make sure your code is easy to change, scale, and maintain. Here’s a quick breakdown:
- Single Responsibility Principle (SRP): Each class should focus on one job or responsibility.
Example:
Bad Example: A class that handles both data storage and business logic:
public class EmployeeService
{
public void AddEmployee(Employee emp)
{
SaveEmployee(emp); // Saving to the database
}
private void SaveEmployee(Employee emp)
{
// Database logic here
}
}
Good Example: Separate classes for data storage and business logic:
public class EmployeeService
{
private readonly EmployeeRepository _repository;
public EmployeeService(EmployeeRepository repository)
{
_repository = repository;
}
public void AddEmployee(Employee emp)
{
_repository.SaveEmployee(emp);
}
}
public class EmployeeRepository
{
public void SaveEmployee(Employee emp)
{
// Database logic here
}
}
2. Use Descriptive Names
Choosing clear and descriptive names for your variables, methods, and classes is important. It makes your code easier to understand.
Example:
Bad Example:
int n; // What does 'n' mean?
Good Example:
int employeeCount;
double totalSalary;
Tip: Stick to .NET’s standard naming conventions like using PascalCase for class and method names and camelCase for variables and parameters.
3. Keep Methods Short and Simple
Each method should do only one task. Long methods are hard to understand and harder to test.
Example:
Bad Example: A method that does too many things at once:
public void ProcessOrder(Order order)
{
ValidateOrder(order);
CalculateTotal(order);
SaveOrder(order);
SendNotification(order);
}
Good Example: Break the method into smaller parts:
public void ProcessOrder(Order order)
{
ValidateOrder(order);
CalculateTotal(order);
SaveOrder(order);
NotifyCustomer(order);
}
private void NotifyCustomer(Order order)
{
// Notification logic here
}
4. Avoid Code Duplication
Don’t write the same code in different places. Instead, create reusable methods or classes.
Example:
Bad Example: Duplicate logic in two methods:
public void CreateInvoice(Order order)
{
var tax = order.Amount * 0.2;
var totalAmount = order.Amount + tax;
// Additional logic
}
public void CreateReceipt(Order order)
{
var tax = order.Amount * 0.2;
var totalAmount = order.Amount + tax;
// Additional logic
}
Good Example: Reusable method:
public class FinancialService
{
public decimal CalculateTotal(decimal amount)
{
var tax = amount * 0.2m;
return amount + tax;
}
}
5. Write Unit Tests
Writing unit tests helps ensure that your code works correctly. It also prevents bugs from appearing in the future.
Example:
A simple calculator:
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
Unit Test:
[TestClass]
public class CalculatorTests
{
[TestMethod]
public void Add_TwoNumbers_ReturnsCorrectSum()
{
var calculator = new Calculator();
var result = calculator.Add(2, 3);
Assert.AreEqual(5, result);
}
}
6. Use LINQ for Simplicity
LINQ (Language-Integrated Query) makes it easier to work with collections of data.
Example:
Without LINQ:
var highScores = new List<int>();
foreach (var score in scores)
{
if (score > 50)
{
highScores.Add(score);
}
}
With LINQ:
var highScores = scores.Where(score => score > 50).ToList();
7. Handle Exceptions Carefully
Always handle exceptions using try-catch blocks, but don’t catch generic exceptions like Exception
. It’s better to handle specific exceptions.
Example:
Bad Example: Catching all exceptions:
try
{
// Database code here
}
catch (Exception ex)
{
// Generic handling
}
Good Example: Catching specific exceptions:
try
{
// Database code here
}
catch (SqlException ex)
{
// Handle SQL exception
}
catch (FileNotFoundException ex)
{
// Handle file not found exception
}
8. Use Dependency Injection (DI)
Dependency Injection (DI) is a way to make your code more flexible and loosely connected.
Example:
Bad Example: Hard-coded dependency:
public class OrderService
{
private readonly EmailService _emailService = new EmailService();
public void ProcessOrder(Order order)
{
_emailService.SendOrderConfirmation(order);
}
}
Good Example: Using Dependency Injection:
public class OrderService
{
private readonly IEmailService _emailService;
public OrderService(IEmailService emailService)
{
_emailService = emailService;
}
public void ProcessOrder(Order order)
{
_emailService.SendOrderConfirmation(order);
}
}
9. Refactor Regularly
Refactoring means cleaning up your code over time. Tools like ReSharper or Visual Studio Code’s refactoring features can help make this easier. Regular refactoring helps keep your code organized and efficient.
10. Use Async and Await for Better Performance
Using async
and await
in .NET improves performance by allowing methods to run asynchronously, especially when working with tasks like fetching data.
Example:
Synchronous method:
public void FetchData()
{
var data = _repository.GetData();
ProcessData(data);
}
Asynchronous method:
public async Task FetchDataAsync()
{
var data = await _repository.GetDataAsync();
ProcessData(data);
}
Dipak Pakhale
A skilled .Net Full Stack Developer with 8+ years of experience. Proficient in Asp.Net, MVC, .Net Core, Blazor, C#, SQL, Angular, Reactjs, and NodeJs. Dedicated to simplifying complex projects with expertise and innovation.
Reply