Visual C#: Easy Code Refactoring
Introduction
Code refactoring is very important, a necessity especially if you use agile methodologies. Even if you are following other classic software development methods, you do need to refactor your code in order to promote re-usability, improve readability & performance etc.
You can easily use the tools available in Visual C# to easily refactor your code.
Let's start with this very simple console application. We will try to use Visual C# tooling/code refactoring features to help improve this code in below sections.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CodeRefactoringDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter first number: ");
int firstNumber = int.Parse(Console.ReadLine());
Console.WriteLine("Enter second number: ");
int secondNumber = int.Parse(Console.ReadLine());
Console.WriteLine("Sum is: " + (firstNumber + secondNumber));
Console.WriteLine("Average is: " + (firstNumber + secondNumber) / 2);
Console.WriteLine("Press any key to exit: ");
Console.ReadKey();
}
}
}
Remove & Sort Usings
We can clearly notice a lot of usings that we may never use in this program. We can easily fix this using Remove & Sort using feature, like so:
This results in only one using being left out (that we are actually using in this program):
using System;
Extract Method
The next "issue" with this program is that we are carrying out our work without using helper methods. This will result in highly un-maintainable + un-reusable code! Let's use the Extract Method feature to refactor existing code, create & use these helper methods. Let's select all code that we use to get input from the user & extract this to a single method, which we could call again (if required) to re-get user's input:
You will need to give an appropriate name to this new helper method:
The resulting code now becomes (with all above refactoring applied):
using System;
namespace CodeRefactoringDemo
{
class Program
{
static void Main(string[] args)
{
int firstNumber;
int secondNumber;
GetInput(out firstNumber, out secondNumber);
Console.WriteLine("Sum is: " + (firstNumber + secondNumber));
Console.WriteLine("Average is: " + (firstNumber + secondNumber) / 2);
Console.WriteLine("Press any key to exit: ");
Console.ReadKey();
}
private static void GetInput(out int firstNumber, out int secondNumber)
{
Console.WriteLine("Enter first number: ");
firstNumber = int.Parse(Console.ReadLine());
Console.WriteLine("Enter second number: ");
secondNumber = int.Parse(Console.ReadLine());
}
}
}
Let's do the same to those operations happening inside the Console.WriteLine call. This will help us in invoking the same operation again (if required) & so promotes code reuse (showing extracting the Sum method, the same process applies to Average as well):
Also, lets put all the code related to displaying the results in another method, the resulting code would now look like:
using System;
namespace CodeRefactoringDemo
{
class Program
{
static void Main(string[] args)
{
int firstNumber;
int secondNumber;
GetInput(out firstNumber, out secondNumber);
DisplayResults(firstNumber, secondNumber);
Console.WriteLine("Press any key to exit: ");
Console.ReadKey();
}
private static void DisplayResults(int firstNumber, int secondNumber)
{
Console.WriteLine("Sum is: " + Sum(firstNumber, secondNumber));
Console.WriteLine("Average is: " + Average(firstNumber, secondNumber));
}
private static int Average(int firstNumber, int secondNumber)
{
return (firstNumber + secondNumber) / 2;
}
private static int Sum(int firstNumber, int secondNumber)
{
return (firstNumber + secondNumber);
}
private static void GetInput(out int firstNumber, out int secondNumber)
{
Console.WriteLine("Enter first number: ");
firstNumber = int.Parse(Console.ReadLine());
Console.WriteLine("Enter second number: ");
secondNumber = int.Parse(Console.ReadLine());
}
}
}
Regions
Let's use the regions feature to further organize the code. You can easily group all private methods that we extracted above & put them into a region called Private Methods (say):
The resulting program (after collapsing the region) would look like (improves readability):
Surround With
We have already used this feature above (regions). Now lets use this same tooling to add a global exception handler to our code:
This would result in:
Rename
You can easily rename methods, variable, etc using this feature. This also takes care of renaming all code that is dependent, for e.g. if you rename a method call, it will also rename the actual method definition and this is the real deal right?
Let's rename GetInput to GetUserInput like so:
Enter the new name for this method:
You can now see a preview of this change & what all dependent code would be renamed as well:
Conclusion
By leveraging Visual Studio / C# tooling or features, we can easily refactor our code to help improve code quality, readability, performance, & reuse among many other improvements.
Code Sample
Download complete code from here. (link is dead)
Other Languages
This article is also available in the following languages:
Dutch: Gemakkelijk Code Refactoring met behulp van Visual C#