ReSharper has already made a reputation for itself as a tool for managing complexity, and in ReSharper 7 we are proud to introduce two new refactorings that make the task of managing complex and unwieldy code a little bit easier.
What do you do when a class gets too big? Chances are, you try to break it up into smaller classes. This process is common enough for ReSharper to support it via the aptly named Extract Class refactoring. The idea is simple: decide which members need to be extracted, figure out how to manage usage issues (if any), and ReSharper does all the work.
Here’s an example: a
Person class that has lots of address details that are better kept in a separate class:
To give the various address properties a separate class, we can fire off the refactoring either from the context menu or, for example, by selecting the relevant properties in the Solution Explorer and using the Refactor This menu:
The dialog that pops up lets you pick the properties you want to extract, as well as the name of the extracted class and its instance name in the class that uses it:
The refactoring offers options for keeping the element accessible directly in the originating class:
The options are as follows:
None means the member is only accessible via the aggregated variable.
Create copy basically creates a complete replica of the original member that is in no way tied to the extracted class. Existing code continutes to use the original member rather than the extracted one.
Create Delegating Wrapper creates a wrapper around the contained member. This wrapper simply marshals the calls to and from the encapsulated member. For example, if we delegate the
City property, the following code will be generated:
In addition, the Extract Class dialog box shows an illustration of any possible access issues that may arise when the extraction is performed. For every member you select in the list box, ReSharper will indicate other members that use it:
And, in a similar fashion, when ticking the boxes next to members to be extracted, ReSharper will indicate other members that will be extracted to preserve correctness. For example, extracting only the
PrintCity() method will show the following:
…and will result in the following generated code:
And finally, there might be situations where you get a genuine usage conflict: for example, attempting to extract a
private property that’s still being used in the owner class. In this case, ReSharper will show you a stop sign and offer different ways of fixing the issue:
The options for the fix are fairly self-explanatory
Make public turns the member public.
Create accessor keeps the member private but gives it an accessor so the original class can still get to it.
Do not apply fix does not do anything, leaving you with code that will not compile.
Please note: at the moment, the Extract Class refactoring supports only C# but we’re considering introducing a VB.NET version in one of subsequent versions.
Transform Out Parameters
We’ve all been there: starting out with a method that has just a single return value, but then realizing that we’d also like to return some other value from that same method. The typical solution to the problem is to introduce
out parameters, for example:
An alternative to implementing the above method is to have a single return type of
Tuple<Person,bool>, and that’s exactly what the Transform Out Parameters refactoring does. Simply invoke it on a member you want to transform…
The dialog that is displayed shows all the
out parameters that can be transformed — useful in case you have many:
After performing the refactoring, we predictably end up with a method that no longer takes the
out parameter but instead returns a
Tuple, with all the usages updated accordingly:
It’s important to note that the refactoring is available for both C# and VB.NET. Since it uses the
Tuple class, it’s mainly applicable to projects that use .NET Framework 4 and greater, though in the case of a single
out parameter in a
void method this refactoring will let you move the parameter to the output value irrespective of the version of .NET being used.
And last but not least, adding extra parameters after you are already returning a
Tuple is fine as well: ReSharper will simply ask you if you want to append to the existing tuple, and if you do, it will simply expand this tuple to accomodate the additional value.
To sum things up, the refactorings presented here are two small steps in our never-ending war against complexity in software development. We sincerely hope you find them useful. Best of luck, and stay tuned for more exciting features to be covered soon!