C#:
Refactoring

How to:

Let’s refactor a simple C# method that calculates and prints the sum of an array of numbers:

Before Refactoring:

public class Calculator
{
    public void CalculateSum()
    {
        int[] numbers = { 1, 2, 3, 4, 5 };
        int sum = 0;
        for (int i = 0; i < numbers.Length; i++)
        {
            sum += numbers[i];
        }
        Console.WriteLine("The sum is " + sum);
    }
}

After Refactoring:

public class Calculator
{
    private readonly int[] _numbers;

    public Calculator(int[] numbers)
    {
        _numbers = numbers;
    }

    public int CalculateSum()
    {
        return _numbers.Sum();
    }

    public void DisplaySum()
    {
        Console.WriteLine($"The sum is {CalculateSum()}");
    }
}

// Usage:
var calculator = new Calculator(new[] { 1, 2, 3, 4, 5 });
calculator.DisplaySum();

By refactoring, we’ve separated concerns, made the Calculator class more flexible by allowing it to take any array of numbers, and leveraged LINQ to make the sum calculation more concise.

Deep Dive

Refactoring has its roots in the smalltalk programming community and was popularized in the 1990s by Martin Fowler’s book “Refactoring: Improving the Design of Existing Code”. Over the years, it’s become a fundamental part of agile methodologies and good coding practices.

There are various approaches to refactoring, such as Red-Green-Refactor in Test-Driven Development (TDD). It ensures that refactoring doesn’t introduce bugs by starting with a failing test, making it pass, and then cleaning up the code.

When implementing refactoring, it’s crucial to have a comprehensive test suite to ensure that no functionality gets broken during the process. Automated refactoring tools, like ReSharper for C#, can also aid in this process by providing safe ways to change code structures. However, tooling should be supplementary to a deep understanding of the codebase and coding principles.

See Also