Tuesday, January 17, 2012

ReSharper versus Eclipse

A small note: This article is about different refactoring and productivity options in Eclipse and VS+ReSharper. I could write tons of pages between these differences. After writing about ONE feature, I realized that this would be one really huge blog post if I didn't break it down into smaller posts. So: I'll try to describe one feature per blog post.


1. Introduction
For those of you who don't know, ReSharper is a refactoring/productivity-tool for the Visual Studio IDE, written by JetBrains. Refactoring is basically the process of changing the internal structure of code, without modifying it's external behaviour. Eclipse has had built-in refactoring support for as long as I have used it (couple of years), whereas Visual studio has had some simpler refactoring tools. However, with the ReSharper-extension, you get a lot of new refactoring options. And, bottom line: It's awesome and I'm starting to become slightly addicted to it.

I usually write a lot of Java. I have done some Java EE using the RestLet framework and a lot of Android programming the latest months or so. The Eclipse IDE is usually a good fit for these activities. Being used to Eclipse, I'm also used to some nifty features which are not found in Visual Studio. Sure, VS has some refactoring capabilites, but it's quite limited. For instance, I'm used to hitting CTRL+1 in Eclipse in order to bring up the Quick Fix-menu. This is the one I use most frequently in both Eclipse and with ReSharper, so I'll start with this feature.


2. A glance at the quick fix feature
Suppose you want to use the generic List interface in Java. Since it's a generic interface, it takes a generic type argument too. For the sake of argument (no pun intended), let's say that you're accessing a database containing employee-data and you're feeding the data for a specific employee into an Employee-object. That would cause you to create a list of the type List<Employee>. In Eclipse, creating and populating such a list could look something like the following:

List<Employee> employees = DatabaseWrapper.GetAllEmployees();

Simple enough. However, the above code wouldn't compile since the compiler has to be able to actually find the List-interface, which is part of the java.util package. So, you would add one more line to make it compile:

import java.util.List;
List<Employee> employees = DatabaseWrapper.GetAllEmployees();

Then again, perhaps your Employee class resides in another package called myapp.data where you store all your DTO:s (data transfer objects). It's not uncommon to modularize your application this way. This would cause us to add another import statement:

import java.util.List;
import myapp.data.Employee;
List<Employee> employees = DatabaseWrapper.GetAllEmployees();


Still not that many extra words to add to your source. BUT: As projects and source files grow, these import statements are actually quite tedious to maintain. Not only to add, but to remove as well when you suddenly realize that you don't need that list anymore. Some class files can have A LOT of import statements, which makes auto insertion quite useful.

The solution is the "Quick Fix" feature. Press CTRL+1 in Eclipse to bring this one up. You'll get something like figure 1:

Figure 1: Quick Fix in Eclipse

You'll select your import, and Eclipse will add your import to the top of the file. Note the small lightbulb to the far left, which indicates that a quick fix is available.


Now, using Visual Studio 2010 and ReSharper 6.1 instead, you can basically do the very same thing. The Quick Fix in ReSharper is (by default) available through ALT+ENTER instead. For a project similar to the Java program above, this would give us the situation in figure 2:

Figure 2: Quick Fix in Visual Studio 2010 with ReSharper 6.1
As in Eclipse, we get a small lightbulb, indicating a quick fix. C# / .NET doesn't have "package" names, but namespaces instead. The idea, however, is similar. We need to add import statements, and the quick fix allows us to automate this. Usually, this should rather be written as:

var employees = DatabaseWrapper.GetAllEmployees();

But in order to illustrate the functionality, I'm not using the "var" keyword.



3. Is this all the quick fix does?
The answer here is simple: No. The quick fix can do a lot more, both the Eclipse version and the ReSharper version has a lot more capability than adding and removing imports. One of the more important aspects for me is the ability to generate code. This comes in handy when writing unit tests and doing test driven development in general where you'll usually want to write how you interact with your code before the actual implementation.

For instance, using the Employee-example above, we might know that we want to obtain a list of employees from a DatabaseWrapper object. We might not have written the DatabaseWrapper class or decided how the GetAllEmployees() method in it should be implemented, but we know it should be there. Trying to use a non-existent class will obviously give us a compilation error, but it will also trigger the Quick Fix:

In Eclipse, the quick fix would give us the alternative as seen in figure 3:

Figure 3: Generating a new class with the Eclipse Quick Fix

In Visual Studio + ReSharper, we would get figure 4, instead:


Figure 4: Generating a new class with the ReSharper Quick Fix


In Eclipse, this creates a new file with the same name as the class. The generated source code is placed within this file. Anything else would have been odd, since Java demands that a class is placed in a compilation unit with the same name. In C#, classes don't have to be placed in a source file with identical name, and ReSharper places the newly generated class in the same file where you used the quick fix.

Usually, but not always, in C# I would want to place my classes in files with matching names. This is no problem. Just place the marker over the class name, hit ALT+ENTER again and select "Move to another file to match type name", as seen in figure 5:


Figure 5: Move class to file with matching name

Note: If ReSharper creates an internal class instead of a public one: Use the quick fix over the "internal" keyword and select "To public".

Now, the next step in both Eclipse and Visual Studio would be to use the quick fix again and repeat this step with the GetAllEmployees() method, which will create a static method in the class, where you initialize your list. The idea is the same as before: CTRL+1 or ALT+ENTER and select the fix.


4. So, which one is better? (Conclusion)
First of all, one should be aware of the fact that while Eclipse is free, ReSharper costs money. However, this might be money well spent in order to increase productivity. ReSharper is available as a fully functional 30-day demo, so it can easily be tried out anyway.

Second of all: This blog post is in no way a complete, comprehensive review of either Eclipse or ReSharper. There is a lot of "little things" that I did when doing this demo that I simply didn't explain and took screens of. It would result in a too large blog post with too much sidetracking.

Both the ReSharper and the Eclipse quick fixes has its pros and cons, but my initial feeling is that the ReSharper-version tends to be less cluttered with irrelevant choices. Writing this, I did find one nice feature with the ReSharper quick fix, though. I wrote a small mock implementation of the GetAllEmployees() to get the code to compile. The implementation looked like this:

public static List<employee> GetAllEmployees()
{
   var employees = new List<employee>();
  
   employees.Add(new Employee("Eric", "Lavesson", "Software developer"));
   employees.Add(new Employee("John", "Doe", "Guy who fetches coffee"));
  
   return employees;
}


I saw that ReSharper offered a quick fix to use the collection initializer instead (that is, initializing the list at creation instead of calling the .Add everytime). I used the quick fix and ended up with:

public static List<Employee> GetAllEmployees()
{
   var employees = new List<Employee>
         {
            new Employee("Eric", "Lavesson", "Software developer"),
            new Employee("John", "Doe", "Guy who fetches coffee")
         };

   return employees;
}


... Which, for me, is a really nice refactoring feature to have. Now, the Java language and the C# language has some differenses, which the available quick fixes of course is dependent on. For instance, ReSharper also has the really nice option of converting some code (such as for loops et cetera) into Linq-code. For obvious reasons, this doesn't work in Eclipse as this is a language restriction (Linq is .NET-specific), not a refactoring question.

All in all, the two features are very much alike. And, at the end of the day, this is the command I use most of the time in both environments.


5. What's next?
I'm going to write at least one more blog post about refactoring options in Eclipse and VS+ReSharper. Next time, I'll probably look at a couple of renaming and code navigation options instead.

... And perhaps a keyboard shortcut reference to show how commands are mapped in Eclipse VS VS+ReSharper..?

4 comments:

  1. Hi Eric,

    Thanks for the posts. One quick comment. When create the class in step 3, instead of using Alt+Enter to afterwards move to matching file, press Ctrl+R+O (Move to Folder) and in the dialog start typing the name of the project/folder. That way you have the file in the correct project, which most likely isn't the test one but the actual code.

    ReplyDelete
    Replies
    1. Hi.

      Thank you for that comment - I have actually looked for that functionality since I usually end up with the classes in my test projects (and then moving them to the correct project)

      This advice makes my life inside VS a bit easier ;)

      Delete
  2. Visual Smarter is a good tool to try. It is an add-on for Visual Studio. It makes .NET coding easier and smarter.

    http://visualsmarter.blogspot.com/

    ReplyDelete