ReSharper 2017.2 Help

Keymap:

Reduce algorithm complexity and promote modularity

Just about every developer has found himself in a situation where they had a complicated algorithm in a single, virtually unreadable method, that was entangled together with other methods in a class. For example, say you have a general-purpose class for solving equations:

The above equation solver is hard-coded, meaning that to substitute a different solver, you would have to manually replace each instance. Let’s start by taking it out into a separate class. To do this, we use the Move to Another Type refactoring (F6):

Then, we need to specify the class to move the method to. In order to separate concerns better, we pick a separate class called QuadraticEquationSolver for this:

Now that the method has been moved, let’s try taking the discriminant out to a separate calculation. This is easy – we simply select the discriminant calculation and invoke the Extract Method refactoring (Ctrl+Alt+M):

Now, let’s suppose that, after a while, we find a safer solver for quadratic equations. To factor it into the program, we’ll first need to create an abstract base class QuadraticEquationSolverBase. We use the Extract Superclass refactoring refactoring available in the Refactor This menu (Ctrl+Shift+R):

In the dialog that shows up, we get to pick which members will be promoted upwards. We only want the CalculateDiscriminant method:

We add an abstract definition of the Calculate() method (previously called Quadratic()) and end up with the following base class:

We also got rid of the static keyword anywhere with the assumption that the implementations of QuadraticEquationSolverBase will be handled by a lifetime manager within our code. Consequently, ReSharper reminds us to add the override keyword to the renamed Calculate method in our QuadraticEquationSolver class:

Now, let’s say we found a safer version of the quadratic equation solver. Let’s implement it. First, we use the Create derived typecontext action on our base class:

Then, we are asked to implement members on this type, which we do:

Finally, we provide an implementation, making use of the base class’ CalculateDiscriminant() method: