12 Simple Clean Code Tips in .NET

Writing clean code is essential for maintainability, readability, and scalability.

Here are 12 simple tips to help you write cleaner code in .Net, each illustrated with bad and good code snippets.

1. Use Meaningful Names

Bad Code

public class C
{
    public void M()
    {
        var a = 10;
        var b = 20;
        var c = a + b;
    }
}

Good Code

public class Calculator
{
    public void AddNumbers()
    {
        var firstNumber = 10;
        var secondNumber = 20;
        var sum = firstNumber + secondNumber;
    }
}

Explanation: Use meaningful names that explain the purpose of the variable, class, or method.

2. Avoid Magic Numbers

Bad Code

public double CalculateCircumference(double radius)
{
    return radius * 3.14 * 2;
}

Good Code

public double CalculateCircumference(double radius)
{
    const double Pi = 3.14159;
    return radius * Pi * 2;
}

Explanation: Use constants for magic numbers to make the code more readable and maintainable.

3. Use String Interpolation

Bad Code

string name = "John";
int age = 30;
string message = "Name: " + name + ", Age: " + age;

Good Code

string name = "John";
int age = 30;
string message = $"Name: {name}, Age: {age}";

Explanation: String interpolation is more readable and easier to manage than concatenation.

4. Avoid Deep Nesting

Bad Code

if (user != null)
{
    if (user.IsActive)
    {
        if (user.HasPermission)
        {
            // Do something
        }
    }
}

Good Code

if (user == null || !user.IsActive || !user.HasPermission)
{
    return;
}

// Do something

Explanation: Flatten your code by handling exceptional cases first and returning early.

5. Use Guard Clauses

Bad Code

public void ProcessOrder(Order order)
{
    if (order != null)
    {
        if (order.IsValid)
        {
            // Process order
        }
    }
}

Good Code

public void ProcessOrder(Order order)
{
    if (order == null || !order.IsValid)
    {
        return;
    }
    // Process order
}

Explanation: Guard clauses help reduce nesting and make the code more readable.

6. Use Dependency Injection

Bad Code

public class UserService
{
    private readonly UserRepository _userRepository = new UserRepository();

    public void CreateUser(User user)
    {
        _userRepository.Add(user);
    }
}

Good Code

public class UserService
{
    private readonly IUserRepository _userRepository;

    public UserService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public void CreateUser(User user)
    {
        _userRepository.Add(user);
    }
}

Explanation: Dependency Injection improves testability and maintainability by decoupling dependencies.

7. Single Responsibility Principle

Bad Code

public class User
{
    public void AddUserToDatabase(User user)
    {
        // Add user to database
    }

    public void SendWelcomeEmail(User user)
    {
        // Send email
    }
}

Good Code

public class User
{
    public void AddToDatabase(UserRepository userRepository)
    {
        userRepository.Add(this);
    }
}

public class EmailService
{
    public void SendWelcomeEmail(User user)
    {
        // Send email
    }
}

Explanation: A class should have one reason to change. Separate concerns into different classes.

8. Use Async and Await for Asynchronous Code

Bad Code

public Task<string> GetData()
{
    return Task.Run(() =>
    {
        // Simulate long-running task
        Thread.Sleep(2000);
        return "Data";
    });
}

Good Code

public async Task<string> GetData()
{
    await Task.Delay(2000); // Simulate long-running task
    return "Data";
}

Explanation: Use async and await for better readability and performance of asynchronous code.

9. Use Ternary Operators for Simple Conditions

Bad Code

string status;
if (isActive)
{
    status = "Active";
}
else
{
    status = "Inactive";
}

Good Code

string status = isActive ? "Active" : "Inactive";

Explanation: Ternary operators can simplify simple conditional assignments.

10. Encapsulate Conditionals

Bad Code

if (age > 18 && !isMember)
{
    // Do something
}

Good Code

if (IsEligibleForOffer(age, isMember))
{
    // Do something
}
private bool IsEligibleForOffer(int age, bool isMember)
{
    return age > 18 && !isMember;
}

Explanation: Encapsulate complex conditionals into methods to improve readability.

11. Avoid Using Static Classes for Everything

Bad Code

public static class Utility
{
    public static int Add(int a, int b)
    {
        return a + b;
    }
}

Good Code

public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

Explanation: Use static classes only when the class is stateless and only for utility functions.

12. Prefer Composition Over Inheritance

Bad Code

public class Animal
{
    public void Eat() { }
    public void Sleep() { }
}
public class Dog : Animal
{
    public void Bark() { }
}

Good Code

public class Animal
{
    public void Eat() { }
    public void Sleep() { }
}
public class Dog
{
    private readonly Animal _animal = new Animal();
    public void Bark() { }
    public void Eat() { _animal.Eat(); }
    public void Sleep() { _animal.Sleep(); }
}

Explanation: Composition is often more flexible and easier to manage than inheritance.

Conclusion

Applying these clean code principles can significantly improve the quality of your code, making it easier to read, maintain, and extend. Remember, writing clean code is a continuous practice, and these tips are a good starting point to help you on that journey.