DEV Community

DotNet Full Stack Dev
DotNet Full Stack Dev

Posted on

You Should follow these 12 clean code tips if you are a .NET developer

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.

📌Explore more at: DotNet Full Stack Dev
🌟 Sharing would be appreciated! 🚀

1. Use Meaningful Names

Bad Code

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

Good Code

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

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;
}
Enter fullscreen mode Exit fullscreen mode

Good Code

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

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;
Enter fullscreen mode Exit fullscreen mode

Good Code

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

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
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Good Code

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

// Do something
Enter fullscreen mode Exit fullscreen mode

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
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Good Code

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

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

Good Code

public class UserService
{
    private readonly IUserRepository _userRepository;

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

    public void CreateUser(User user)
    {
        _userRepository.Add(user);
    }
}
Enter fullscreen mode Exit fullscreen mode

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
    }
}
Enter fullscreen mode Exit fullscreen mode

Good Code

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

public class EmailService
{
    public void SendWelcomeEmail(User user)
    {
        // Send email
    }
}
Enter fullscreen mode Exit fullscreen mode

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";
    });
}
Enter fullscreen mode Exit fullscreen mode

Good Code

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

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";
}
Enter fullscreen mode Exit fullscreen mode

Good Code

string status = isActive ? "Active" : "Inactive";
Enter fullscreen mode Exit fullscreen mode

Explanation: Ternary operators can simplify simple conditional assignments.

10. Encapsulate Conditionals

Bad Code

if (age > 18 && !isMember)
{
    // Do something
}
Enter fullscreen mode Exit fullscreen mode

Good Code

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

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

Good Code

public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}
Enter fullscreen mode Exit fullscreen mode

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() { }
}
Enter fullscreen mode Exit fullscreen mode

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(); }
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)