While technically used in DevOps software development approaches, code refactoring can benefit developers and development teams no matter what coding methodology you use: be it waterfall, agile, Scrum, DevOps, or a mixture. At the end of the day, refactoring code is about one thing: making your code easier to read, more efficient, less error-prone, and easier to maintain. Okay, so that is four things. Either way, today, we are going to cover the topic of code refactoring in C# for .Net developers.
What is Code Refactoring?
Code refactoring is the practice of taking previously written code and rewriting it to make it more efficient. The idea is simple enough: reduce extraneous code in your software and apps to make the technical cost - the price of fixing errors further down the road - much lower. Reducing the redundant and convoluted code directly affects the performance of your software but also the readability of the code behind it. This makes it easier to add upgraded functionality, fix issues, perform QA tasks, and prevent future issues or bugs.
Another key benefit to code refactoring your C# code is that it helps you avoid code rot. As you may be aware, code rot occurs when you have too much redundant code, spaghetti code, or just sloppy coding practices. Your code can get this way from outdated practices, lack of coding standards in a development team, poorly planned updates or patches, and overtime in general as more and more developers add to the codebase.
Code Refactoring Techniques
Below you can find some of the best code refactoring tips for C# and .Net developers.
Eliminate Redundant Code
One of the best ways to refactor your code is to find redundant lines or blocks of code. Look out for multiple lines of code that do the same exact thing with the exception of a slight difference. If you encounter this a lot, odds are you can approach your code differently. Instead of having a bunch of lines that essentially do the same thing, consider wrapping them all together in a loop or other structure aimed at achieving the same goal.
Refactoring IF Statements in C#
This may be a surprise to some, but there are developers that write their C# If statements without using brackets. This might be (slightly) faster for you to write, but avoid doing it. Remember: you want your code to be clear and readable. Add brackets to your If statements to make it easier, at a glance, to decipher your intent.
Concatenating Strings in C#
In my early days of coding, I was very guilty of this C# programming no-no. When I would concatenate strings, the temptation was always to use the + operator to string together, well, strings. On the surface, this might not seem so bad, but if you stop to think about it, you will realize that it isn't the most efficient way to achieve the joining of multiple strings. The reason why? Because you are creating multiple objects, which, in turn, take up more memory.
To avoid this, you can instead use the String.Concat("","","") function instead. Unlike the + operator, this method of joining strings only creates a single object.
Eliminate Extra Functions
When writing longer programs, you might tend to create similar functions - or the same exact function - multiple times. Sometimes you may not even realize you are doing this and end up with several functions that are all named differently but that all serve the same purpose. Not only is this a waste of resources and time, but it goes against the very idea of why we create functions in the first place - to have reusable code.
If you find yourself in this situation, remove the duplicate functions and simply call the existing function instead. This is a quick way to reduce the amount of code in your software and improve efficiency.
While we are a big fan of commenting code, it is important to keep in mind the best practices for commenting in C#. Remember the purpose of comments: to make your code and its intent easier to understand. When you add too many comments, comments that ramble, or comments that explain obvious snippets of code, you actually decrease the readability of your code.
One great way to refactor your code is to go through and remove unnecessary comments or comments that no longer apply (such as from old snippets of code you are no longer using or that applied to previous versions of the program).
Create Functions When Possible
A great way to increase the performance of your applications, as well as the readability of your code, is to put your common tasks into functions. This is particularly true if you find that your app uses certain sections of code over and over again. Taking those repetitive sections and creating a function out of them, then calling them instead will help you eliminate a lot of lines of code potentially. It is also just good coding practice. By calling the function(s) instead of writing the blocks of code over and over, you not only increase readability and performance but also reduce the number of coding mistakes in your applications.
A common mistake for newer developers is to create overly complicated conditional statements. Even veteran programmers can fall into this trap. Always review your conditionals to make sure the logic is sound and that you are not repeating yourself and evaluating a condition multiple times when you could have just done it once. One clue to finding conditionals that can be slimmed down is to search for really long conditionals. Try to see if you can eliminate one of the conditional checks or rewrite the statement entirely to slim these types of statements down.
Refactor Prior to Updating
As we update, patch, and add new features to our programs, our codebase gets more and more convoluted if we are not careful. This is especially true of code that has not be refactored. With this thought in mind, always make sure you refactor code before you add any new features.
When you do add new features, keep refactoring in mind as you write your code to eliminate the need to refactor your new features further down the line.
Plan Your Code Refactoring
Finally, one of the smartest things a developer or software development team can do before trying to make their code more efficient is to actually plan the refactoring process. Budget for time and resources as part of the refactoring plan and make sure you understand the overall end goal. Are you looking just to increase readability? Are you aiming to use less memory or optimize performance? Knowing these goals and having an overall plan will help you decide which approach to take and ensure your team stays on track. The last thing you want is for developers to go into the codebase and start randomly searching for things to "optimize". Think of it as a road trip with no map.
Test Your Code as You Refactor
As a bonus code refactoring tip, always remember to test your code. Test it often. As you make changes to the codebase, even minimal changes can have disastrous, far-reaching effects if you are not careful. As you refactor one section of your C# code, make sure to test it so you know it performs as it originally did. Remember, the goal is not to change the way the program works; it is to make the code work (and read) better.
What Are Code Smells or Smelly Code?
Code smells are characteristics or signs in your codebase or source code that indicate there is some sort of problem with the code itself or the programming logic behind it. Code smells are not unique to C# or .Net but instead exist in all programming languages. Code smells are not technically a bug but more of an indicator that your program is not running in the best possible method.
Code smells are typically found through code refactoring efforts or code inspection. JetBrains has a tool called ReSharper that is pretty handy in sniffing out that smelly code too. We mention the phrase code smell here because it is a common term you hear associated with code refactoring. Examples of smelly code include using the concatenator or + operator to string together strings inside of loops or explicitly throwing an exception.
When Not to Refactor C# Code
There are some instances where you do not need - or perhaps want - to refactor code. If you are trying to make a deadline for product launch, for example, beginning the code refactoring process might throw a monkey-wrench into things. It is impossible to accurately predict how much code will need to be refactored and structure a timeline around that if you are under pressure of a product release deadline. If anything, always make sure to build time into the software product lifecycle for code refactoring ahead of time if you intend to implement code refactoring as a common practice.
Another time you might want to reconsider refactoring your C# and .Net code is if you are deciding to rewrite a program from scratch. Obviously, in these instances, reworking your code would be a huge waste of time.