Joe White’s Blog

Life, .NET, and Cats


Archive for February, 2007

ReSharper, day 28: Really Extract Static Method and Extract Property

Wednesday, February 28th, 2007

Welcome to day 28 of my 31 Days of ReSharper.

Today, I’ll touch on a couple more refactorings (besides Introduce Parameter, discussed yesterday) that you can use in conjunction with Extract Method.

Really Extract Static Method

ReSharper won’t always let you extract a static method (e.g., if the code references instance fields or methods). But you can get there in two steps, by first extracting the method, and then using the Make Method Static refactoring.

ReSharper's Make Method Static dialog box

I haven’t used this refactoring much, so I won’t go into details. I just wanted to note that it’s there.

Extract Property

ReSharper doesn’t have an “Extract Property” refactoring. But you can get there in two steps: first you extract a method, and then you use Method to Property.

ReSharper's Method to Property dialog box

There’s also a Property to Method refactoring, if you ever need to go the other way.

ReSharper, day 27: Extract Method

Tuesday, February 27th, 2007

Welcome to day 27 of my 31 Days of ReSharper.

Today’s topic is Extract Method, arguably the second most useful refactoring of all time. (Rename, of course, is the first. I’ll cover it in a couple of days.)

ReSharper's Extract Method dialog box

  • Method name is pretty obvious.

  • Declare static is automatically grayed out if the expression uses any instance fields, methods, or properties. I’m not sure why this is. When you’re calling a method, it makes sense, but fields and properties could just get passed into the newly-extracted method, if ReSharper allowed it.

  • Return value seems to serve no purpose whatsoever. I’ve never seen it enabled. And it either says “No return value”, or it’s blank (even though ReSharper clearly does know the return type — it’s shown correctly in the “Signature preview” box). I don’t know if it’s just buggy, or if it was a deliberate design decision to put a blank combo box here.

  • Parameters. ReSharper decides which parameters you need, and fills them in. While the grid looks like the one in the Change Signature dialog, it’s nowhere near as full-featured: here all you can do is rename and reorder. You can’t change parameters’ types or anything like that.

    ReSharper suggests names for the parameters it decides you need, but that’s a one-time thing when the dialog opens. You have no way of dropping down a list of other suggestions.

    If you uncheck a parameter, it won’t be passed; instead ReSharper will generate a local variable and initialize it to three dots, ..., which guarantees that the compiler will gently suggest that you fill in something else.

Extracting with extra parameters

I’ve often wished that ReSharper’s (and Delphi’s, too, for that matter) Extract Method dialog had an option to add more parameters. But I was thinking about it this evening, and realized that — with ReSharper, at least — it’s unnecessary.

Suppose I’ve got some setup code for a test, and it does this:

_foo = new Foo(42);

And suppose I want to pull that line of code into a new method, InitializeFoo(), that takes an int parameter. What I wanted was for the Extract Method dialog to show me the code it was going to write, and for it to let me highlight the 42 and say “hey, tack on another parameter for this expression.”

Well, duh. They’ve already got a feature for doing exactly that! I have to actually hit OK to extract the method first, but then I can highlight the 42 in the code editor and do an Introduce Parameter. And it’ll automatically update the call site to pass in the literal 42, so everything just works.

ReSharper, day 26: Change Signature

Monday, February 26th, 2007

Welcome to day 26 of my 31 Days of ReSharper.

Ever had three functions that all take the same parameters, but each one in a different order? If so, Change Signature is the feature for you.

ReSharper's Change Signature dialog box

ReSharper’s Change Signature dialog lets you change anything and everything about a method signature. There are other ReSharper features for changing a method signature in specific ways, such as Introduce Parameter. But this is where you go for stuff there isn’t a shortcut for. Here, you can:

  • Rename the method. If you select Delegate via overloading method, it will even put in a method with the old name, that does nothing but call the new one. In case that’s ever useful.

  • Change the return type.

  • Add a parameter. You must specify a default value, which is what will be passed at all the call sites. But sometimes you don’t want to pass a constant value every time, in which case, see the next section.

  • Remove a parameter. ReSharper will not check to make sure the parameter is unused, so this may result in non-compilable code. (They do have a feature for safely deleting parameters, among other things, which I’m saving to cover on Day 31.)

  • Rename a parameter. Alas, ReSharper does not provide variable-name suggestions here, even if you press Ctrl+Space.

  • Reorder parameters.

In all of these cases, ReSharper takes care of updating all the call sites.

Non-constant values for new parameters

When you add a new parameter, ReSharper wants to keep your code compilable, so it needs to modify all the call sites that already call this method. That means it needs something to pass. This is a required field; you have to specify something to pass from all the call sites.

So what happens if you don’t want to pass the exact same thing from every call site? You have a few options:

  • Don’t use Change Signature; manually add the parameter instead. Then the compiler will take you to all of the call sites — probably. (I’ve been bitten by this one when there turned out to be other overloads.) Not recommended in any but the simplest of cases; that’s why we have tools to do this stuff for us.

  • Use a default value, and remember to go back and change it. Also not recommended. Human memory is not that good. That’s why you’re using ReSharper in the first place. You should only use a default value like null if it really is the most reasonable thing to pass.

  • Use a nonsense expression, like asdfjkl, that won’t exist at any of the call sites. ReSharper will let you do this, but (no surprise) you’ll end up with non-compilable code. This is actually good, in this case: it guarantees that the compiler will take you to every call site, where you can make a case-by-case determination of what to pass in.

  • Use an expression that you hope will work most places. If you’re passing a Foo object, you can just type Foo as the default value, in the hopes that most of the call sites will be on classes that already have a Foo property. We’ve often had decent luck with this one.

  • Use Introduce Parameter instead. If you can use Introduce Parameter, it’s better than Change Signature, because Introduce Parameter will do the right thing. But it only works if you can express the new parameter in terms of things the method knows about.

ReSharper, day 25: Introduce Parameter

Sunday, February 25th, 2007

Welcome to day 25 of my 31 Days of ReSharper.

I’ve talked about two of the three Introduce refactorings (Introduce Variable and Introduce Field). Today, I’ll cover the third: Introduce Parameter.

ReSharper's Introduce Parameter dialog box

Apart from the top pixel of the “Type” combo getting cut off, and the lack of an “Introduce constant” checkbox, this looks an awful lot like Introduce Variable. It works a lot like it, too. Stubborn blue highlights, all that stuff.

Sounds pretty mundane. But here’s the thing: it works. It’s surprisingly smart.

Here’s a silly example:

_tilesWide = GetTilesWide(_previewer);
...
private int GetTilesWide(Control control)
{
return (control.Width + TileWidth - 1) / TileWidth;
}

Suppose you want to write unit tests for this function, but you don't want to create Control instances in your tests. You could just highlight control.Width and do an Introduce Parameter.

Oddly enough, the first suggestion for a parameter name is i, instead of the more obvious width. (width is available in the combo box dropdown, though.) It's also a bit of a shame that it doesn't suggest controlWidth.

Supposing that I did type in controlWidth for my variable name, the resulting code would look like this:

_tilesWide = GetTilesWide(_previewer, _previewer.Width);
...
private int GetTilesWide(Control control, int controlWidth)
{
return (controlWidth + TileWidth - 1) / TileWidth;
}

At that point, the control parameter turns gray — you aren't using at anymore. So you can cursor onto it and use Alt+Enter to remove the unused parameter, leaving you with code that doesn't have scary dependencies and is much easier to unit test:

_tilesWide = GetTilesWide(_previewer.Width);
...
private int GetTilesWide(int controlWidth)
{
return (controlWidth + TileWidth - 1) / TileWidth;
}

(If the method had been public, then the parameter wouldn't have shown up in gray, because ReSharper isn't brave enough to look at public methods. Hopefully that will be fixed when they add #pragma support to suppress individual warnings, which they tell me will be in the next release. But hang in there; there are other ReSharper features that know how to delete parameters.)

What's cool isn't so much that it adds the parameter. That's really no cooler than adding a local variable. What's cool is that it automatically does the Right Thing at all the call sites. If one of the call sites was passing an arbitrarily complicated expression that resulted in a Control instance, that's fine: it would turn into an arbitrarily complicated expression followed by .Width.

It works for extracting more complicated expressions, too. You can use, not only other parameters, but also static methods, and even instance methods and properties on the current class. ReSharper will just do the right thing.

Here's an example that's a little closer to real life. I may or may not be anywhere close to what we were actually doing in the code, but if the rest of this post is a work of fiction, it doesn't make it any less cool.

processor.ProcessFile(FileType.Foo);
...
public void ProcessFile(FileType fileType)
{
string fileName = this.Configuration.GetFileName(fileType);
...
}

We were trying to get rid of the Configuration property, because it was scary and hard to get instantiated in a test harness. So we started by extracting a parameter for this.Configuration.

processor.ProcessFile(FileType.Foo, processor.Configuration);
...
public void ProcessFile(FileType fileType, Configuration configuration)
{
string fileName = configuration.GetFileName(fileType);
...
}

What really wowed me (and it may seem like a simple thing to you, but I've tried to write a parser before, so I appreciate this kind of stuff) is that it just did the right thing at the call site: it passed processor.Configuration. The parameter was automatically passed in terms of the right instance of the right object.

That's just cool.

ReSharper, day 24: Introduce Field

Sunday, February 25th, 2007

Welcome to day 24 of my 31 Days of ReSharper.

Yesterday I talked about ReSharper’s Introduce Variable refactoring. Today’s topic is Introduce Field.

Adding a field is a lot like adding a variable, but there are extra options:

ReSharper's Introduce Field refactoring dialog, accessed through Ctrl+Shift+R

It does the usual variable name suggestions (which follow the naming conventions you specify in ReSharper Options).

Like Introduce Local Variable, it has a Replace all occurrences of expression checkbox. But because Introduce Field affects an entire class, the blue highlights, and the blue stripes in the color bar, become more useful in seeing how many places the expression will be replaced (although the fact that they won’t go away is still annoying).

Introduce Field also has that goofy behavior where they use Cancel to mean Highlight All, instead of using it to mean Cancel. If you want the thing that’s really Cancel, you need to click Cancel and then press Esc. (And if you want the thing that’s really OK, you need to click OK and then press Esc. Eww.)

Not much more to be said about the basic settings. The options speak for themselves fairly well.

Trying to write tests

If you write unit tests, you’ll notice that none of the “Initialize in” options are much good in a test-fixture class. “Current member” might be useful on occasion, but it’s not usually what you want. (And “Constructor” and “Field declaration” shouldn’t even be available if you’re working in a [TestFixture] class, IMHO. They’re just begging for inter-test dependencies.)

I sent in a feature request to add “Initialize in [SetUp] method” to ReSharper, but they closed it as “Won’t Fix”, claiming that it could be implemented as a plug-in. If that’s true, they have got a long way to go on the documentation for the ReSharper plug-in API, because they don’t have any refactoring samples at all. It doesn’t even look like they’re planning to write any; they don’t have a section for them. So if anyone wants to write a ReSharper plug-in that adds a radio-button choice to an existing dialog box, and uses that new choice to change the behavior of an existing refactoring, I’ll just wish you the best of luck right now.

It’s not the end of the world; you can still do an Introduce Field properly. It’s just not as nice as most things in ReSharper. You have to manually scroll to the SetUp method, and stuff like that. (grin)

If you want to use Introduce Field in a test fixture, here’s how to make it work, until and unless they get around to writing those plug-in docs:

  1. Use Introduce Field, and select “Current member”.

  2. Cut the assignment that ReSharper just generated, and paste it into your [SetUp] method.

Not that hard, really. Just irritating. They’ve spoiled me by making everything so easy, that it’s frustrating when they take something I do all the time and flat-out refuse to make it as easy as it should be.

ReSharper, day 23: Introduce Variable (and, introducing Ctrl+Shift+R to refactor)

Friday, February 23rd, 2007

Welcome to day 23 of my 31 Days of ReSharper.

Today, and for the rest of the 31 days, I’ll be talking about ReSharper’s support for refactoring, which is much improved over the handful of refactorings that ship with Visual Studio 2005.

Refactor This with Ctrl+Shift+R

ReSharper has a targeted context menu for refactoring. It contains only the refactorings that make sense at the current cursor position, or based on the current selection. You invoke it with Ctrl+Shift+R.

Here’s an example of what it looks like:

ReSharper's Refactor This context menu, showing refactorings that are available in the current context

This menu contains other refactoring commands, and some of them have their own keystrokes defined. (They’re full-fledged Visual Studio commands, so you can add or change the keymappings.) You may learn some of those other keystrokes, if there are refactorings that you use often. But I really like the low cost of entry. All you need to remember is Ctrl+Shift+R.

Introduce Variable

Introduce Variable creates a new local variable, and initializes it to the selected expression. Then it replaces the selected expression with a reference to the new variable.

ReSharper's Introduce Variable refactoring dialog, accessed through Ctrl+Shift+R

Here’s a rundown of the options:

  • Variable type. I don’t think I’ve ever seen this combo box enabled; it’s always locked in on the exact type of the expression. If you want to use a base type instead, you’ll have to introduce the variable first, and then change the type.

  • Variable name. ReSharper’s variable name suggestions kick in here, of course. One suggestion is filled in, and you can see the others by dropping down the combo box.

  • Replace all occurrences of expression. Since you’re introducing a local variable, this only replaces occurrences within the current method. If the same expression shows up more than once, then you probably want to check this option most of the time; but it can change your code’s behavior, through side effects and aliasing and whatnot, which is probably why this option isn’t checked by default.

  • Introduce constant. This could have been a separate refactoring, but they rolled it into Introduce Variable. This checkbox is only enabled if the expression can be evaluated at compile time.

Ditching the blues

When you bring up this dialog, if the expression shows up more than once in your method, ReSharper will highlight all the usages in blue. It will also show blue tick marks in the color bar.

A ReSharper 'feature' leaves expressions highlighted in blue even after you cancel out of the Introduce Variable dialog

If you Cancel out of the Introduce Variable dialog, the blue highlight doesn’t go away, and neither do the blue stripes in the color bar. I reported this as a bug, and they said nope, not a bug: this is on purpose, so you can look at all the places that expression occurred. This is the first time I’ve ever heard of using a Cancel button to find usages. (Guys, maybe there should be another button besides OK and Cancel? Maybe a “Show Usages” button?)

Update: I didn’t realize it when I first wrote this, but the blue highlight also sticks around after you click OK. So no matter what you do, if you bring up this dialog, you need to remember to press Esc after you close it. One extra, needless step, every single time. Isn’t ReSharper supposed to be there to make things easier, and make common tasks take less time? Grumble.

So anyway. It took me a couple of months, but I eventually found an easy way to dismiss all the blue: just press Esc. This is a good thing to know, because otherwise, it’s pretty stubborn: until you press Esc, that highlight is going to stick around until you either close the file or delete the code.

Note: Tomorrow’s article isn’t quite done yet, and I’ll be out of town this weekend. So tomorrow’s article will get posted on Sunday.

ReSharper, day 22: Generating code with Alt+Ins

Thursday, February 22nd, 2007

Welcome to day 22 of my 31 Days of ReSharper.

So I’ve covered Alt+Enter, which is all about fixing code. Sometimes it does this by generating new code (e.g., when you change a class to implement an interface, and Alt+Enter has to generate method implementations), but the focus is on fixing errors and warnings.

Today I’ll cover Alt+Ins, which is specifically geared toward generating code.

The Alt+Ins menu

When you press Alt+Ins, a menu appears, showing all possible code-generation commands. This menu always shows all of its commands, and grays out the ones that aren’t available (as opposed to other ReSharper menus that only show the available items).

Alt+Ins generates code within a class, so if you press Alt+Ins when the cursor isn’t inside a class, everything will be grayed out.

ReSharper's Generate menu, invoked by Alt+Ins

Common features of the Alt+Ins wizards

Every one of the Alt+Ins commands brings up a wizard. Typically, the wizard pages will contain lists where you can select things (fields, for example) that you want taken into consideration by the generated code.

There are two types of lists in these wizard pages: there’s the checked list, and the regular list.

A checked list from one of ReSharper's Alt+Ins Generate wizards

The checked list, as seen above, has checkboxes next to each item. It seems to be used when you can select zero or more items (i.e., when “no selection” makes sense).

A (non-checked) list from one of ReSharper's Alt+Ins Generate wizards

The regular list has no checkboxes; you make your selection by selecting one or more items in the list. It’s a standard multiselect listview, so you can Shift+click and Ctrl+click to select multiple items.

The regular list seems to be used when you must select at least one item, although this isn’t actually enforced. You can get some amusing results by Ctrl+clicking the only selected item to de-select it, and then moving on through the wizard.

If you want to select everything in a list, it’s easy. In the checked list, press Ctrl+A and then Space. In the regular list, just press Ctrl+A.

Generate Constructor

This command generates a parameterized constructor to initialize some or all of the fields on your class. It shows a checked list where you can select which fields you want to initialize.

Features worth noting:

  • Plumbing. If the base class constructor takes parameters, the newly-generated constructor will automatically take the same parameters, and pass them to the base constructor. These parameters will be put first in the parameter list. (Later, I’ll talk about a feature that lets you re-order parameters if you want.)

  • Multiple constructors. If the base class has multiple constructors, there will be a second wizard page that asks you which constructors to call. If you select more than one, then more than one new constructor will be generated.

  • Dumb. There’s no checking to see whether constructors already exist. If you tell it to generate a constructor with the same parameters as one you’ve already got, it will happily do it, and then give you red squigglies because the code doesn’t compile. It’s one of only two Alt+Ins commands that don’t check to make sure they’re generating good code.

Generate Property

There are three commands: Read property, Write property, and Read-write property. They all work the same: they ask you which fields to generate properties for, and then they go do it.

This one is smart. If you’ve already created some properties, then those fields won’t be selectable in the wizard. If you’ve already created properties for all of your fields, then all of the property-generation commands in the menu will be disabled.

Implement Interface Member

This one is actually identical to using Alt+Enter to Implement Members, except that it only shows interface members, not abstract methods.

Override Inherited Member

This is, again, just like Alt+Enter to Implement Members, except that (a) it doesn’t show interface members, and (b) it shows virtual (non-abstract) methods as well as abstracts.

Equals() and GetHashCode() will be shown in this list, but keep in mind that there’s a cooler way to do those — use the “Equals and GetHashCode” command in the Alt+Ins menu, described below.

Generate Delegating Members

This is really handy when you’re writing an adapter or a decorator, or just when you want to make your code more Demeterish. It generates code that looks like this:

public int Length
{
get { return _inner.Length; }
}
public void GetFoo(FooSpec spec)
{
return _inner.GetFoo(spec);
}
public void DoSomething()
{
_inner.DoSomething();
}

In this example, I delegated the Length property and the GetFoo() and DoSomething() methods to the _inner field. The Generate Delegating Members wizard makes this the matter of a few clicks and can do several members at once, and it’s subject to a lot less human error than doing it by hand.

You can delegate to any field or property (so you can delegate to something that’s lazy-initialized, for example). First you select the field or property, and then on the second page, you select the members to delegate.

Like Generate Constructor, this one is also dumb. It will let you delegate the same method signature more than once, which will lead to non-compilable code.

Generate Equals and GetHashCode

It’s not common to need to override Equals and GetHashCode, but when you do, I think some automated assistance would be quite welcome.

First the wizard asks you which fields you want to compare in Equals(), and then it asks which of those fields you want to use in calculating GetHashCode(). It’s smart enough to know that if a field isn’t used in determining equality, then that field had better not be used in calculating the hash code (i.e., if you don’t check a field on the first page, then it’s not available on the second page).

If any of the fields you select are reference types, there’s a third wizard page, which asks if there are any fields that can be assumed to be non-null. If so, it can simplify the implementation of GetHashCode().

Here’s an example of the resulting code. _name is assumed to be non-nullable; _address is not.

public override bool Equals(object obj)
{
if (this == obj) return true;
Foo foo = obj as Foo;
if (foo == null) return false;
if (_x != foo._x) return false;
if (_y != foo._y) return false;
if (!Equals(_name, foo._name)) return false;
if (!Equals(_address, foo._address)) return false;
return true;
}
public override int GetHashCode()
{
int result = _x;
result = 29*result + _y;
result = 29*result + _name.GetHashCode();
result = 29*result + (_address != null ? _address.GetHashCode() : 0);
return result;
}

ReSharper, day 21: Code transformations with Alt+Enter

Wednesday, February 21st, 2007

Welcome to day 21 of my 31 Days of ReSharper. Today, I’ll wrap up the topic of Alt+Enter.

We’ve already seen how Alt+Enter can fix errors and warnings by modifying your code: it shows the red light bulb, and you can press Alt+Enter to see quick fixes.

There are also discretionary quick fixes — things that you can do to your code, but that you don’t have to. These are just things that people do a lot, so ReSharper automates them to make them a little easier.

The discretionary quick fixes are indicated with a yellow light bulb.

These can be a bit hard to find, because you have to have the cursor in the right place. That’s true of the quick fixes for errors and warnings, too, but you can see the places where those apply; they’re red or gray or squiggly; and you can jump to the next one with F12. With the discretionary quick-fixes, there’s no visual clue until you put the cursor in the right place and wait half a second or so, and there’s no keystroke to jump to the next one. You pretty much have to either (a) already know they exist, or (b) stumble onto them.

Which is why I’m covering a few of them, so you’ll know what to look for.

Removing unused braces

Suppose you have an if block that used to contain multiple statements, so you had curly braces. And now you’ve changed the code so that there’s only one line of code, so you don’t want the curly braces anymore.

Where to put the cursor: At either the open or the close curly brace (either right before it, or right after).

ReSharper's discretionary quick fix for removing unneeded braces in an 'if' statement

Changing visibility

If you position the cursor over a private, protected, internal, or public keyword, you’ll get a yellow light bulb. Press Alt+Enter, and you can change the visibility. It doesn’t save much typing, but occasionally it’s handy.

Where to put the cursor: Anywhere within the visibility keyword.

ReSharper's discretionary quick fixes for changing a member's visibility

Split Variable and Assignment

If you’ve got a variable that’s being assigned as part of its declaration, and now you want that assignment to be conditional or some such, you can use Split Declaration and Assignment to quickly split the assignment into a separate statement.

Where to put the cursor: over either the variable name, or the ‘=’ sign.

ReSharper's discretionary quick fix for splitting a variable declaration from its assignment

Join Variable and Assignment

Reverse transformations are good. Join Declaration and Assignment moves the variable declaration to the line where the variable is first assigned.

Where to put the cursor: on the line where the variable is first assigned, over either the variable name or the ‘=’ sign.

ReSharper's discretionary quick fix for joining a variable declaration and its first assignment

Here’s what it looks like after the transformation. Note that it moved the declaration down to the assignment, rather than moving the assignment up to the declaration, so it’s not going to break any ordering dependencies in your code.

After using ReSharper's discretionary quick fix to join the variable declaration and its first assignment

Invert If

This is one of my favorites. It just reverses the condition on an if statement, and swaps the “if” and “else” blocks. It’s purely a cosmetic change, with no effect on what the code actually does.

Where to put the cursor: on the if keyword.

Sounds pretty predictable, and I won’t give a boring example. But it is a little bit smarter than just inverting the condition and the blocks. Here’s an example of why it’s my favorite:

An 'if' statement that spans an entire method: code that ReSharper can improve

This happens from time to time: an if statement that spans the entire method. Here’s what happens after Invert If:

After using ReSharper to invert the full-method 'if'

It realizes that the if statement is the last thing in the method, so it generates a return to bail out of the method early if there’s nothing to do. One less level of indentation on a large block of code, and one less line of code in the method. Cool!

ReSharper, day 20: Fix errors and warnings with Alt+Enter

Tuesday, February 20th, 2007

Welcome to day 20 of my 31 Days of ReSharper.

I’ve been talking about Alt+Enter, and how it can fix a couple of different kinds of errors, but I’ve only scratched the surface. It can fix all sorts of things — not everything, but quite a bit. And it’s not just errors; it can fix quite a few warnings (grays) as well.

So today I’ll cover a few more examples. These are not meant to be exhaustive.

A note about “disable this warning”

When you’re over a ReSharper warning in the code (either gray code, or a blue squiggly), and press Alt+Enter, one of the quick fixes will be to disable the warning, e.g., “Disable warning ‘Unused private member'”. My advice is, avoid this command.

I tried it once, because I thought it meant “put in a comment or a #pragma or something to flag that this particular occurrence is okay”. It doesn’t. It means “never check for this condition again, ever, anywhere”. And there’s no Undo for it. You have to dig through ReSharper Options until you find the right setting to turn it back on.

Fortunately, you can disable this command entirely (on the same page where you go to clean up after you selected it unintentionally). Go to ReSharper Options > Highlighting, and uncheck “Show ‘Disable warning …’ action”.

Fixing error: Return type doesn’t match

Suppose you’re upgrading code from VS 2003 to VS 2005, and are starting to use generics. So you refactor a utility method to return IList<Foo>; instead of IList. But now all the places that called it are broken.

ReSharper's Quick Fixes for an unmatched return type

Here’s one of the call sites that’s assigning the method result into an IList. In this example, you would want to select Change type of ‘errors’ to ‘IList<Exception>’. And you can do the same thing at each other call site. Beats re-typing the same return type over and over.

Fixing error: Abstract method in concrete class

If you’re in the middle of introducing a template method, you might end up with abstract methods in a class, but you haven’t marked the class itself as abstract yet.

ReSharper's Quick Fixes for an abstract method in a non-abstract class

In this example, you just cursor to the abstract keyword, press Alt+Enter, and select Make ‘ClassName‘ abstract. Sure, it’s not that much typing to just scroll to the class declaration and type abstract there; but the nice thing about this one is that the squiggly shows up right there in the code you’re working with, so you don’t need to scroll to the top of the file.

Fixing warning: Variable is assigned but never read

ReSharper can fix variables that are declared but never used, but that’s not very interesting. Variables that are one-way — read but never written, or vice versa — are a little more interesting. So here’s a variable that’s assigned in its declaration, but then never gets read:

ReSharper's Quick Fixes for a variable that is written, but never read

When it says “assignment(s)”, it means it. It will remove any assignment that happens at the declaration, and it will remove any other assignments that happen anywhere else. This is particularly striking when you have a field that’s never read; ReSharper will remove every assignment in every method. This can be very handy when you’re ripping out code you don’t need anymore.

Be careful with this one. If any of the assignments have side effects, you will lose those side effects. In the above example, the value would never get added to the list box.

Fixing warning: Field is read but never written

ReSharper's Quick Fix for a field that is read, but never assigned

This one is cool. You just select Initialize field in constructor(s), and then you’re done. ReSharper automatically adds a new parameter to your constructor and generates the code to assign it.

Oddly, there isn’t a quick-fix to create a read/write property. I’m sure I’ve seen that as a quick-fix, but apparently not here.

Fixing warning: Unused parameter

ReSharper's Quick Fix for an unused parameter

Yep. When you use ReSharper to remove an unused parameter, it automatically fixes all the call sites to keep the code compilable.

Often, this yields more gray code, especially when you had one object that you were plumbing through seven layers of code, and then you refactor so you don’t need it anymore. Remove it at the bottom layer, and now the next layer up has a gray parameter.

You might not see this very often, though, because ReSharper only seems to mark a parameter as gray if you’re in a private method. This is silly, of course; you would care about unused parameters in public methods at least as much as in private methods.

F12 and Alt+Enter

That’s just a taste of what Alt+Enter can do to fix errors and warnings. When you see stripes in the color bar, it can be worth it to just keep hitting F12 (jump to next error) and Alt+Enter, and seeing what ReSharper can do to help clean up your code.

ReSharper, day 19: Implement Members with Alt+Enter

Monday, February 19th, 2007

Welcome to day 19 of my 31 Days of ReSharper.

Visual Studio 2003 and 2005 both had features for helping you implement interfaces. VS2003’s features were a lot more finicky. VS2005 was much better. ReSharper is better yet. Let’s take a look.

When you create a new class, and add : IFoo to its declaration, you’ll get a red squiggly, because you now have code that won’t compile (because there are no methods on your class to satisfy that interface). When you put the cursor on the squiggly code, you’ll get a red light bulb, and when you press Alt+Enter, you’ll see the Implement members quick-fix.

ReSharper's quick fix for Implement Members

The same thing happens if you have a non-abstract class, but its parent class has abstract methods. But in this case, there’s a second quick-fix: Make ClassName abstract, which I’ll ignore since it’s pretty self-explanatory.

Note that if your descendant class is already marked abstract, you won’t get a red squiggly for your unimplemented abstract methods, since they aren’t errors. That means you don’t get a quick-fix. ReSharper still has a way to automate these overrides, though, which I’m currently scheduled to cover on Thursday (Day 22).

The Implement/Override Members wizard

The first page of ReSharper's Implement/Override Members wizard, which lets you select which of the missing members to override

The first page of the wizard lets you select which members you want to implement. Everything is selected by default. It would be silly to uncheck anything in the list, because then you’d be left with still-unimplemented interface members or abstract members, so your code still wouldn’t compile.

Note the toolbar buttons in the top right, above the list. These toggle the list between a tree, where everything is grouped by interface, and a flat list, which is sorted alphabetically. This only affects the way they’re displayed in the wizard. ReSharper will still generate the members in any old order it feels like.

There are three options down below: Copy documentation comments, Explicit interface implementations, and Wrap interface implementations in regions. They’re fairly self-explanatory, and I have yet to use any of them, so I won’t cover them further. On to the second page.

The second page of ReSharper's Implement/Override Members wizard, which lets you select which properties you want to generate backing fields for

The second page is where ReSharper’s version becomes much cooler than Visual Studio’s, because you can automatically create backing fields for any or all of your properties. It will add the fields (following the naming conventions you’ve set up in ReSharper Options), and will read and write them from the property getters and setters. Methods, as well as any properties you don’t check in this list, will get placeholder code that throws a NotImplementedException.

If you want to check all of the fields in the list, press Ctrl+A and then Space.

Then you click Finish, and it generates the code for you.

Note: the “Sort alphabetically” checkbox on page 2 is the same setting as those toolbar buttons on page 1: if you check “Sort alphabetically”, you get a flat sorted list, whereas if it’s unchecked, you’ll get the tree. It’s actually just one option for both pages (changing it one place will change it in the other), although they present it differently on the two pages for some unknown reason.

So, there’s Implement Members. Simple but useful. The only option it’s missing is to add a constructor that sets initial values for some or all of those backing fields. There’s an automated way to do that, too (also slated for Day 22), but it’d be nicer if there was an extra wizard page for it. Still, the ability to just implement everything all at once, and create backing fields at the same time, is pretty sweet.


Joe White's Blog copyright © 2004-2011. Portions of the site layout use Yahoo! YUI Reset, Fonts, and Grids.
Proudly powered by WordPress. Entries (RSS) and Comments (RSS). Privacy policy