The Silent Evil: How to Eliminate Duplicate Code in C#


“Duplication is the root of all evil.” – Robert C. Martin
Duplicate code is one of the sneakiest violations of clean code. It seems harmless at first, but over time it multiplies, changes inconsistently, and causes hard-to-find bugs.
In this article, we’ll explore how to recognize, prevent, and eliminate duplicate code in C#, keeping your code DRY (Don't Repeat Yourself).
What is duplicate code?
It’s any block of code repeated in two or more places, with the same meaning or purpose. It can appear as:
Identical (direct copy-paste)
Slightly modified (different names or constants)
Conceptually the same (same logic, different context)
❌ Example of duplication:
decimal CalculateOrderTotal(Order order)
{
return order.Items.Sum(i => i.Price * i.Quantity);
}
decimal CalculateInvoiceTotal(Invoice invoice)
{
return invoice.Lines.Sum(i => i.Price * i.Quantity);
}
Why is it a problem?
❌ Risk of inconsistency: you change one part, but forget the other.
❌ More complex maintenance: every change has to be done in multiple places.
❌ Longer, harder-to-read code.
How to avoid it? Refactor!
✅ Extract common methods:
decimal CalculateTotal(IEnumerable<LineItem> items)
{
return items.Sum(i => i.Price * i.Quantity);
}
Use it in both contexts:
decimal orderTotal = CalculateTotal(order.Items);
decimal invoiceTotal = CalculateTotal(invoice.Lines);
Use shared classes or services
If the logic is more complex, put it in a reusable class.
public class TotalCalculator
{
public decimal Calculate(IEnumerable<LineItem> items)
=> items.Sum(i => i.Price * i.Quantity);
}
DRY ≠ abstract everything too early
Beware of premature abstraction. Forcing abstraction too soon may lead to fragile and less clear code.
Duplicate 2–3 times first, then consider abstraction.
Not every similarity is duplication.
DRY in naming and constants
Repeated names and values are also duplication.
❌ Repeated code:
if (status == "ACTIVE") { ... }
✅ Centralized constant:
public static class StatusCodes
{
public const string Active = "ACTIVE";
}
DRY in tests
Watch out for wild copy-pasting in unit tests too. Use common setups, helper methods, Theory, InlineData, etc.
DRY ≠ copy-paste between projects
Did you write a nice function in another project? Don’t copy it.
Extract it into a shared library (.NET class library)
Or make it a private NuGet package.
Conclusion
Writing code without duplication isn’t just an aesthetic choice. It’s a survival strategy for projects that must evolve, grow, be read, and maintained by teams over time.
"Code is written once, but read (and changed) a hundred times."
In the next article, we’ll talk about comments: when they’re really needed and when they signal something’s wrong.
Subscribe to my newsletter
Read articles from Developer Fabio directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Developer Fabio
Developer Fabio
I'm a fullstack developer and my stack is includes .net, angular, reactjs, mondodb and mssql I currently work in a little tourism company, I'm not only a developer but I manage a team and customers. I love learning new things and I like the continuous comparison with other people on ideas.