New Refactorings in ReSharper 7

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.

Extract Class

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!

This entry was posted in ReSharper Tips&Tricks and tagged , , . Bookmark the permalink.

4 Responses to New Refactorings in ReSharper 7

  1. Joe White says:

    Can you control the order of the Tuple arguments? I.e., can I choose between Tuple and Tuple (or manually reorder the arguments if there are more than two)?

  2. Joe White says:

    Of course it didn’t handle the angle brackets correctly. Let’s try that again.

    Can I choose between Tuple<Person, bool> and Tuple<bool, Person>?

  3. Dmitry Ivanov says:

    Hi Joe,

    The order of types in angle brackets depends of the source function’s parameters order. You can’t change it right in “Transform Out Parameters” refactoring UI.
    However, you can execute “Change signature” refactoring first, reorder variables and then execute “Transform Out Parameters” refactoring.

  4. Tom says:

    Hi Dmitri,

    I don’t see the extract class refactoring but I do see the out parameter refactoring.
    Maybe my version doesn’t align with yours?

    JetBrains ReSharper 7.0 Full Edition
    Build 7.0.97.60 on 2012-07-25T18:31:00

    Free evaluation 14 days left
    Plugins: none
    Visual Studio 11.0.50522.1.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">