ReSharper coolness of the day: TODOs and NotImplementedException

ReSharper adds much fancier syntax highlighting to Visual Studio. And I recently found an unexpected coolness in how they highlight TODOs.

TODO highlighting

One of the things ReSharper adds is highlighting of TODO comments. By default they’re bold and bright blue (as opposed to the non-bold green of regular comments), making them stand out nicely.

They also have a “To-do Explorer” window that lists all the TODO items in your solution.

NotImplementedException vs. NotSupportedException

Okay, it’s going to feel like I’m shifting gears for a minute here.

The .NET framework includes two exceptions that mean very nearly the same thing: NotImplementedException and NotSupportedException. I always used to have to stop and think about the difference between them, and which one I really wanted, every time I wrote — or read — code that used them.

Just for reference, here’s what they mean:

  • NotImplementedException: Placeholder. Often inserted by a code template. This means that the real code hasn’t been written yet. It’s basically a TODO with teeth.
  • NotSupportedException: Means “this space intentionally left blank”. We made a conscious decision here. This class does not and will not support this method. For example, an interface method that isn’t applicable for a given implementation.

Two great things that taste great together

In ReSharper 4.5, the following code will, under the default settings, highlight blue and bold, just like a TODO comment:

throw new NotImplementedException();

So with ReSharper, I don’t need to stop and think about the difference between NotImplementedException and NotSupportedException. They make it dead simple: if it highlights like a TODO comment, then it’s the one that really means TODO.

As I so often say when I’m talking about ReSharper: Sweet.

ReSharper coolness of the day: generated constructor visibility

If you use ReSharper‘s Alt+Ins to generate a constructor, and you’re in an abstract class, ReSharper is automatically smart enough to make the constructor protected.

This only makes sense. After all, .NET design guidelines recommend that abstract classes shouldn’t have public constructors — you can’t instantiate the class, so while a public constructor is harmless, it’s also misleading.

But… no matter how much sense it makes, it’s cool. It’s one of those little details that make me like ReSharper so much.

Addendum: when you use Alt+Enter to change the constructor’s visibility, public isn’t even on the list. Nice touch.

ReSharper beta license: it’s Diamondback all over again

What is up with people making public betas and then insisting that they be kept top-secret?

I decided to download the ReSharper 4.0 beta, so I could finally get some ReSharpery goodness in Visual Studio 2008. Then I read their license agreement, and it’s almost as bad as the public embarrassment that was the Delphi 2005 beta license. You’d think someone posting a public beta would want advance publicity and grassroots buzz, but I guess not.

Some excerpts (which I will later have to deny ever posting, or indeed reading):

Any and all test results, error data, reports or other information, feedback or materials made or provided by Licensee relating to Software (collectively, “Feedback”) are the exclusive property of JetBrains…

Read that a few times. It says that anything I could possibly have to say about the beta (“reports or other information”), whether I send it to JetBrains or not (“made or provided”), is not mine. Which means I would be in violation of copyright (by illegally copying JetBrains’ intellectual property) if I posted anything on my blog about the beta.

(They note elsewhere that I should treat my feedback as confidential information. My reports or other information, on the other hand, are not confidential; they’re just not mine.)

[“Confidential Information” means] … (iii) the terms, conditions, and existence of this Agreement.

Even though it’s an open beta, and anyone can download it and look at the license agreement, I will hereafter have to disavow any knowledge of said license agreement. I’ll tell you I don’t even know there is a license agreement for the beta. (At least I can admit the existence of the beta itself, if not the beta license. That’s a pleasant change from Delphi betas. Oops — what Delphi betas?)

Licensee’s obligations regarding Confidential Information will expire no less than five (5) years from the date of receipt of the Confidential Information

The first time I read this, I thought it meant I couldn’t talk about ReSharper at all for five years. Fortunately, it wasn’t quite that bad:

«Software» means the ReSharper pre-release software

They were, in fact, smart enough to only make me promise to keep the beta top-secret (along with any other pre-release software they may make public over the next five years). I can still talk about released versions. Whew!

They’re also nice enough to say that I don’t have to disavow knowledge that was already publicly available. Again, a step up from Delphi. But still a disappointment.

Anyway, don’t expect me to help hype their public beta. I wish I could; it looks like it’ll have loads of cool stuff in it. But they don’t want my hype; they want their public beta kept secret… so I will be contractually obligated to disavow this blog post, starting about two minutes from now.

ReSharper Jedi blog

If you use ReSharper or think you might someday, you owe it to yourself to check out Ilya Ryzhenkov’s ReSharper blog. Ilya is one of the ReSharper developers, and he’s also one of the foremost “ReSharper Jedi” — think power users with light sabers.

I just picked up a sweet trick reading his “Jedi Way — Implementing Members” post: if you’re adding a new method to an interface, you can just go ahead and implement the method right there inside the interface. Of course that won’t compile — you can’t have an implementation inside an interface (what do you think this is, Ruby?) — so ReSharper gives you the expected red squiggly. But it also gives you a red light bulb, and offers to move the method body into the implementing classes! (He has screenshots — scroll to the “Jedi Trick Level 3” section in his post.)

(Note: I haven’t had a chance to try this yet — it may only work in the upcoming ReSharper 3.0. Can anyone confirm whether this is available in current versions?)

ReSharper, day 31: Safe Delete

Welcome to day 31 of my 31 Days of ReSharper. (Okay, so it’s a day late. I took yesterday off.)

The last ReSharper refactoring I’m going to cover is Safe Delete. It’s accessible through the Ctrl+Shift+R menu, or directly via Alt+Del.

Safe Delete brings up another of ReSharper’s refactoring wizards. The first page (which, in many cases, is the only page you even see) is pretty boring, since there really aren’t that many different ways to delete something.

The first page of ReSharper's Safe Delete wizard

The general idea of Safe Delete is that it will delete something without breaking your code. It does two things:

  • Checks for problems. If you try to delete a method, and that method is still used somewhere, ReSharper will warn you, and give you a chance to cancel the delete. You can click one of the hyperlinks to jump to the code, or you can show all the problems in the Find Results window.

    ReSharper's Safe Delete wizard, warning of places that still use the member being deleted

  • Carries the changes through. If you delete a parameter, all the call sites will be updated. If you delete a virtual method or an interface method, you get asked if you want to delete it from all the descendant classes as well.

    ReSharper's Safe Delete wizard, asking if you want to delete descendant members as well

Safe Delete is fabulous in theory: if we suspect code is unused, we can confirm that it’s not used and delete it and update all the call sites in a single operation. It even gives us a way to manually check for unused parameters, since ReSharper doesn’t bother checking for unused parameters in public methods. You wouldn’t want to manually run Safe Delete on every parameter of every method in your solution, but when you suspect something’s amiss, it’s a good cleanup tool.

But as I found while I was researching this post, its checks are far from perfect. It seems to do pretty well at carrying the changes through, but it’s got a ways to go on checking for problems first. So:

A word of caution

Always compile just before, and again just after, you use Safe Delete. Because it can break your code.

Here are a couple of cases I found in just a minute or two of poking around:

  • If a method is used as a delegate, and you Safe Delete a parameter, ReSharper will let you. After that, obviously it doesn’t match the same delegate type anymore, so the code won’t compile. (They will warn you if you try to delete the entire method, though, so they’re at least partly delegate-aware.)

  • If you’re overriding a method from another assembly (e.g., you’re overriding System.Windows.Forms.Control.IsInputKey), and you Safe Delete a parameter from your method, ReSharper will delete the parameter without warning you about the ancestor. So the override won’t compile anymore, since there’s nothing with a matching signature for it to override.

I don’t mean to suggest that it’s always going to break your code. Far from it, especially if you’re paying attention. (I knew better than to try deleting a parameter of an event-handling method, I just wanted to see what it would do.) Its checks will catch you in most cases. But it’s still a good idea to compile before and after.

ReSharper, day 30: Rename, including Viral Rename

Welcome to day 30 of my 31 Days of ReSharper.

Today I’m going to talk about that mother of all refactorings, Rename, available via F2. It is, of course, also available through the Ctrl+Shift+R menu.

Now, there’s only so much you can say about a Rename refactoring. Generally, either it works or it doesn’t; there’s a limit to how cool it can be. But ReSharper does manage to pull off a few nice tricks.

Note: Due to a combination of technical difficulties, a lack of planning, and a couple of big snowstorms, I’m currently unable to use ReSharper at home. So today’s post (and perhaps tomorrow’s too) will not have screenshots, and the details will be from memory. Please correct me if I get anything wrong. I’ll try to come back later and clean these up.

Renaming local variables: SyncEdit and suggestions

When you rename a local variable, ReSharper uses SyncEdit (my name for it, not theirs) to let you make the change right there in the editor. It also pops up its list of suggested variable names, so you can select a name from the list.

I’m used to Delphi, where I have to press Esc to end SyncEdit mode and apply my changes. Turns out this is poor preparation for ReSharper, because when you hit Esc in ReSharper’s SyncEdit, it reverts your changes. In ReSharper, you have to hit Enter to apply the change. (Yes, it would’ve made more sense if Delphi did it that way too.)

Now, using Enter to save your changes does make sense, but it has a downside: if the variable-name list is showing, Enter will select the current item in that list. So if you want to name your exception object, say, ex, and you type ex, pressing Enter will not rename your variable to ex — it will rename it to exception, because that’s the first variable-name suggestion that starts with ex.

Here’s the workaround for entering shorter variable names: if you press Esc once, it will dismiss the variable-name suggestions, but will not end SyncEdit. (You need to press Esc again, with the suggestion list already gone, before it will revert your rename.) So you need to press Esc to get rid of the suggestions, and then Enter to apply the rename.

Renaming classes: Viral rename

I have long wished for a viral rename refactoring — one that infects all the code around it. For example, if I had a class called SongFile, chances are I would have a lot of variables called songFile or file, a lot of properties called SongFile, etc. I want a rename that, when I rename SongFile to SongDataStore, infects all those variable names and property names, and renames them too.

ReSharper has it.

Well, mostly, anyway. When you rename a class, you get a wizard, and the first page asks you for the new name; nothing too exciting there. But then it looks for variables and properties that (1) match the type you’re renaming, and (2) have names similar to part of the name that you’re changing. And it will show a second page listing them, and suggesting new names for them all. You can uncheck any that you don’t want to rename, but why would you want to do that?

The only downside is that it doesn’t do the same for descendant classes. But I’ve filed a feature request, so we’ll see…

ReSharper, day 29: Refactoring with interfaces

Welcome to day 29 of my 31 Days of ReSharper.

Working with interfaces is, traditionally, pretty frustrating. You need them when you’re writing testable code, so you can fake the filesystem and pass in null objects, but they’re a pain when you’re trying to follow what the code is actually doing.

ReSharper has several features that make it much easier to work with interfaces. I’ve already covered two, Navigate to Inheritor and the Type Hierarchy view.

Today I’ll cover another ReSharper feature that’s handy when you’re working with interfaces: the “base method” prompt.

ReSharper prompt: Method 'Engine.RoomScreen.Update(int)' implements method from interface 'IScreen'. Do you want to rename the base method?

If you apply a refactoring — for example, a rename — to a method, and that method is there to satisfy an interface, ReSharper will ask if you want to apply that refactoring to the interface instead.

This dialog box kind of klunky — it disrupts the flow of my thinking, and it’s not the easiest question to understand. It just doesn’t work the way I think. Unfortunately, I don’t have any suggestions for improving it.

That said, I do love this feature. If I decide to rename a method, ReSharper will automatically jump in there and ask if I want to rename it on the interface as well. Usually the answer is yes, because that’ll keep the code compilable. (Sometimes the “yes” is preceded by “Oh yeah, that method is from an interface, isn’t it?”).

This also applies to Find Usages. If you try to Find Usages on a method that implements an interface, you’ll get asked “did you mean the method here, or the same method when accessed via the interface?” In this case, you may have to do the search twice to really get all the usages of that method (although if you’re diligent about only using the class through the interface, then you could just answer Yes and only do the search once.)

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

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

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

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.