Introduction
Do you love coding but catch yourself writing the same code again and again? Have you ever paused and thought, “Isn’t there a more efficient way to handle this?”? Fortunately, there is a proven solution—the DRY (Don’t Repeat Yourself) Principle, a core concept that helps developers write cleaner, more maintainable code.
Rather than duplicating the same logic throughout the codebase, developers should define it once and reuse it wherever needed. This approach results in code that is:
Consider you are developing an application that calculates discounts for two customer types: Regular and Premium. Without applying the DRY principle, you might end up repeating the same or very similar logic in several different parts of the code.
Problem Without DRY
public class CustomerService
{
public double GetDiscountForRegularCustomer(double amount)
{
if (amount > 1000)
{
return amount * 0.10; // 10% discount
}
else
{
return amount * 0.05; // 5% discount
}
}
public double GetDiscountForPremiumCustomer(double amount)
{
if (amount > 1000)
{
return amount * 0.20; // 20% discount
}
else
{
return amount * 0.10; // 10% discount
}
}
}
In this case, the discount calculation logic is duplicated with minor differences. If the business rules change, you would have to modify several methods, which increases the chances of inconsistencies and errors.
Applying DRY Principle
Let’s improve the code by applying the DRY principle and moving the shared logic into a single, reusable method.
Move the common logic into DiscountService, where the discount amount is calculated based on the provided parameters, while CustomerService simply passes the required parameters to perform the calculation.
public class DiscountService
{
public double CalculateDiscount(double amount, double highAmountRate, double lowAmountRate)
{
if (amount > 1000)
{
return amount * highAmountRate;
}
else
{
return amount * lowAmountRate;
}
}
}
public class CustomerService
{
private readonly DiscountService _discountService = new DiscountService();
public double GetRegularCustomerDiscount(double amount)
{
return _discountService.CalculateDiscount(amount, 0.10, 0.05);
}
public double GetPremiumCustomerDiscount(double amount)
{
return _discountService.CalculateDiscount(amount, 0.20, 0.10);
}
}
Techniques to Avoid Code Repetition in C#
Use Functions and Methods - The easiest way to reduce duplication is to extract repeated code into methods. This centralizes logic and simplifies updates when requirements evolve.
Leverage Inheritance and Polymorphism - When classes share similar logic with minor differences, inheritance and polymorphism reduce duplication. Define common functionality in a base class or interface, then override it in subclasses as needed.
Utilize Extension Methods - If you frequently perform the same operation on a type, extension methods allow you to write reusable logic without modifying the original class.
Apply Generics - When logic is identical across multiple data types, generics let you write type-independent methods, avoiding duplication.
Advantages of DRY Principle in C#
Easier Maintenance - If all the logic is kept in one place, it’s much easier to update. You don’t have to search through lots of files—just change it in one method, class, or service.
Reduced Risk of Bugs - "Repeating the same code can cause mistakes or make parts of your program act differently. The DRY principle helps by keeping the logic in one place, so your app works the same everywhere and is easier to fix.
Improved Readability - When the same code is written in many places, the project becomes larger and harder to move around in. Following the DRY principle keeps the code shorter and cleaner, which makes it easier for developers to read, understand, and maintain over time.
Faster Development - DRY reduces repetitive work, allowing developers to focus on implementing new features instead of rewriting existing logic. This accelerates development and saves time in the long run.
Consistency Across the Codebase - The DRY principle makes sure that the same piece of logic works the same way everywhere it’s used. This helps the application behave in a predictable and consistent manner, which is especially valuable in large projects or when many developers are working together on the same codebase.
When Is It Acceptable to Repeat Code?
The DRY principle is a best practice, not an absolute rule, and there are situations where repeating code can be perfectly acceptable.
Avoid Premature Abstractions - Hold off on abstraction until duplication is clear. Premature abstractions can make code harder to understand and maintain.
Keep it Simple - Don’t over-engineer for the sake of DRY. Straightforward, stable code can be repeated without harming maintainability.
Choose Clarity Over Cleverness - Sometimes it’s better to keep code separate so it’s easier to follow. Forcing reuse can make the intent harder to see.
Simple Code Wins - If a line is easy to understand and won’t change, just duplicate it—no need for fancy abstractions
Conclusion
The DRY Principle goes beyond reducing repetitive typing—it focuses on creating software that is robust, maintainable, and scalable. By applying DRY in C#, as demonstrated in the example, you help keep your codebase clean, consistent, and well prepared for future changes.