Removing #regions, or "How to keep your code expanded"

In a couple of recent posts, I’ve all but declared war on #regions. I’m not going to regurgitate my reasons but for those of you who go into "you won’t like me when I’m angry" mode when they see a 800-line class condensed down to five, I submit to you not one, but TWO methods for getting rid of them.

Method 1: The VBA way

In this method, I used my newfound knowledge of using regular expressions in Visual Studio’s Find and Replace and recorded a macro. Did some clean-up of the code and voila:

    Sub ClearRegions()
        DTE.Find.Action = vsFindAction.vsFindActionReplaceAll
        DTE.Find.FindWhat = "^:b*\#region.*\n"
        DTE.Find.ReplaceWith = ""
        DTE.Find.Target = vsFindTarget.vsFindTargetCurrentDocument
        DTE.Find.MatchCase = False
        DTE.Find.MatchWholeWord = False
        DTE.Find.MatchInHiddenText = True
        DTE.Find.PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxRegExpr
        DTE.Find.ResultsLocation = vsFindResultsLocation.vsFindResultsNone
        DTE.Find.Action = vsFindAction.vsFindActionReplaceAll
        DTE.Find.Execute()

        DTE.Find.FindWhat = "^:b*\#endregion.*\n"
        DTE.Find.ReplaceWith = ""
        DTE.Find.Target = vsFindTarget.vsFindTargetCurrentDocument
        DTE.Find.MatchCase = False
        DTE.Find.MatchWholeWord = False
        DTE.Find.MatchInHiddenText = True
        DTE.Find.PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxRegExpr
        DTE.Find.ResultsLocation = vsFindResultsLocation.vsFindResultsNone
        DTE.Find.Action = vsFindAction.vsFindActionReplaceAll
        DTE.Find.Execute()
    End Sub

To bind a key combination to a macro

  • Click Tools | Options
  • Select Keyboard from the Environment tree node
  • In the search box, type ClearRegions to find the macro
  • Select it from the list
  • Click in the "Press shortcut keys" textbox
  • You can probably take it from here

So you throw that into a Macro Module, bind it to Ctrl+Shift+3, for example, and henceforth, you can use that shortcut to be free of #regions forever.

If I wanted to be *really* anal about it, I’d extract the duplicate code into a separate method. That way, I could re-use it for a macro to, say, remove triple-slash comments (regular expression: "^:b*///.*\n" ).

Method 2: The ReSharper Way

This method comes courtesy of Wade Grandoni, a non-blogger-who-should from whom I plan to steal blog post ideas until he takes the hint. When we’re done here, removing regions becomes part of the ReSharper reformatting process. I.E. Ctrl+Alt+F (or Ctrl+Alt+Shift+F) and your regions are gone. If it isn’t obvious yet, this method requires ReSharper

To achieve this little bit of magic:

  • Go to ReSharper | Options
  • Under Language Options, expand C#, then Formatting Style
  • Select Type Members Layout
  • Uncheck "Use Default Patterns" and DO NOT BE ALARMED AT ALL THE TEXT THAT APPEARS

What you see at this point is, I think, some default patterns that get applied to your classes when you reformat. And the default is to ignore regions for the most part. To change this find default pattern about halfway down. It’s the one that looks like this:

    <!–Default pattern–>

    <Pattern>

and change it to this:

    <!–Default pattern–>

    <Pattern RemoveAllRegions="true">

Henceforth, whenever you reformat your code, regions will be removed. N.B.: This works only if you have selected the option to "Reorder type members" in the Reformat dialog:

image

If you select this option (as well as any others) the first time, it will be remembered every time you Ctrl+Alt+F or Ctrl+Alt+Shift+F from then on.

If you’re a little confused as to what the rest of that XML is doing in the default patterns, you could delete the entire thing and replace it with the following:

<?xml version="1.0" encoding="utf-8" ?>

<Patterns xmlns="urn:shemas-jetbrains-com:member-reordering-patterns">

  <Pattern RemoveAllRegions="true">

     <Entry />

  </Pattern>

</Patterns>

This is the bare minimum you need to remove regions from your code when you reformat. What the rest of that XML does requires more reading than I’m willing to put in at 6:30 in the morning.

This method has the advantage of less friction while you’re coding in that you don’t need to perform any extra steps to remove regions (assuming you reformat before you check-in, which, of course, you do). On the other hand, Method 1 can be adapted to remove other patterns (like triple-slash comments) and, of course, can be used for the ReSharper-less in the crowd. And neither method will allow you to keep any regions that are, in fact, useful.

Kyle the Regional

This entry was posted in Coding Style, ReSharper. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://kyle.baley.org Kyle Baley

    Was that directed at this particular post? If so, then I’ve been seriously misusing the word “diatribe” for some time.

  • Bob

    diatribe much..?

  • Anonymous

    Thanks for this tip! 5 years later and it still works in ReSharper 6.x. I have a love/hate relationship with region blocks… lately removing them in favor of VS’s own collapsing thing and refactoring long methods into shorter, more manageable routines.

  • Dmitry

    Good or bad it is a matter of personal choice. Period.

    Like them fine, do not like also fine – just keep the code automatically expanded. Problem solved. There are bigger problems that we normally have to deal with.

  • Thorsten

    I went ahead and took the Stylecop CustomPatterns style and commented all region groups out:

    Use this if you want to keep all other cleanup settings, but don’t like regions: (paste into custom Patterns at Resharper.Tools.C#.Type Members Layout)

    < ?xml version="1.0" encoding="utf-8"?>




    Inherit="true">







    Inherit="true">



























































































    Weight="300">
























































    Weight="600">









    Weight="700">







  • Gareth Jones

    thanks for the tip, came in very handy. i dont understand why they are in the product, they are a total code smell. if you need to divide your class up for easier viewing, its way too big – refactor the class into a number of smaller classes with single responsibilities with sensible naming and the problem goes away.

    thanks again!

  • http://melgrubb.spaces.live.com Mel Grubb

    Four words: Regular Expression Search & Replace (I’m not counting the & as a word)\

    Search for ^.*\#(end)*region.*\n
    Replace with empty string

  • Ertan Zanagar

    I used this trick to clean up my regions via R# but if my region is inside a method, it does not get cleaned up.

  • http://geekswithblogs.net/brians Brian Schroer

    Thanks, Kyle.

    I’ve been using your macro for a while, and noticed that after I run it, the “use regular expressions” box is checked the next time I use the Visual Studio Find dialog.

    I modified it to save the original Find options and reset them after nuking the regions:

    http://geekswithblogs.net/brians/archive/2008/05/11/122067.aspx

  • Simon

    I didn’t realize that you were such a region bigot. Next time we’re on a project together, I’ll make sure to put a region around every single line of code in the program. :)

  • http://blogs.dovetailsoftware.com/blogs/kmiller Kevin Miller

    I was wondering why regions kept showing up in my reformatted code.

  • K.Todd Baley

    You guys are all NERDS!!!

  • Wade Grandoni

    Regions can be used to separate large swaths of code into different areas of responsibility in a class. The class is more usable afterwards. Regions are great for this type of scenario.

    I don’t know about you, but this hillbilly’s fur stands up when I see multiple responsibilities and large swaths of code in one class. SRP is violated; Extract Class is the solution (among others)! Regions are a smell, fixing the root cause is a much better approach.

    “What’s wrong with just leaving them be for the people that like them (of which I am one) and use outlining > toggle / expand / whatever”
    There’s mental overhead to translate between different formats. What do you do when working on a class that was created by someone else? Do you format as they have, format as you like, what if three different styles were used? It really gets messy when you add source control to the fray. Merging, checking in, branching, compares and diffs become tedious and error prone.

    Resharper’s Type Member Layout customization feature lets you get all the formatting benefits without any significant effort or mental overhead. Our velocity has improved since adopting it. In the past few days since this has been in place, we haven’t had any merging impediments mentioned at our daily scrums. People complained of merging slow downs every other day with the older “do the best you can approach”.

    Hey Kyle, what do I need a blog for when I can hang out here?

  • http://codebetter.com/blogs/kyle.baley Kyle Baley

    Nothing wrong with that. I do it all the time. The shortcut key is Ctrl+M, then Ctrl+L. I’m pretty sure there is a way to always open files in expanded mode too but for whatever reason, I’ve never looked into how to do it.

  • chrisb

    Whats wrong with just leaving them be for the people that like them (of which I am one) and use outlining > toggle / expand / whatever

    Sure there will be a way to macro that too and you wont be mangling the source for others :)

  • http://www.winterdom.com/weblog Tomas Restrepo

    @Kyle: As long as I’m not on your team, feel free to browbeat anyone you like, I do my own beating from time to time :)

    @Dave: Yes, that sounds like a good reason for removing #regions completely, and certainly having a script for that might be handy. I don’t object to removing stupid uses of editor features; I was merely mentioning that if you really didn’t want #regions at all, disabling the feature seemed like a saner approach to me; at least concerning the sanity of your fellow team members (and depending of who they are, your personal well being ;))

  • http://www.kenegozi.com/blog Ken Egozi

    Where I do use regions:
    Some integration tests that assert the output of a view, or output of any other text-spitting thing (like the precompilation steps of AspView), I need to setup something like
    string expected = @”Some multiline long string”;

    So I tend to wrap that string in a region, to make the test readable

  • Kyle Baley

    Yeah, this is kinda why I didn’t want to get into it again, especially where the audience consists of more than my friends and family.

    You’re right. Some people do like regions. And it is okay. And I hope that doesn’t sound condescending because I don’t mean it to be. It really is a stupid argument to have online. It’s better suited to an amicable, face-to-face discussion over drinks at the pub where we can say things like “you are a slave to your tools” in a tone that sounds more like good-natured ribbing.

    So, once again, for posterity, here are two ways to remove regions and nothing more.

  • Nathan

    So, from your other post, it appears that you basically don’t like Regions because Resharper can’t work with them?

    I don’t get you people who are a slave to your tools. Fine, you don’t like regions. Some of us do and that’s ok.

  • http://codebetter.com/blogs/kyle.baley Kyle Baley

    @Damien: Again, this post wasn’t to argue why regions are good are bad. I’ve done that post already and I have no desire to bring up that religious argument again. *IF* you want to remove them, and *IF* you are in an environment where you can, then these are two of the ways I’ve recently come across to do so.

    @Tom: That’s a nice little tip too. Allows you to pick and choose which regions to remove.

  • http://damien@envytech.co.uk Damien Guard

    You have totally missed the point of these region blocks.

    They are not there for power-users who know the code inside-out. If you know the name or have followed the method in then they don’t get in the way, the section automatically expands. No benefit but no obstacle either.

    If however this is the first time you are looking at this class and want to know what it a. contains data about (expand fields) b. exposes (expand properties) and c. operates on (expose methods) then they are very useful as they have the stuff grouped together.

    What people coming to a system don’t want to see is a thousand lines of methods, properties and fields in a semi-random order. Sure you *can* group them without regions but then you have an undocumented expectation on developers that will no doubt get missed.

    [)amien

  • http://blogs.solidhouse.com/david.woods Dave Woods

    @Tomas: Sometimes you start on a project where everything (or almost everything) is surrounded with a region and it is easier to remove them all and then re-add them to the few spots they were useful.

  • http://www.opgenorth.net Tom Opgenorth

    Another more manual way is via the File Structure View in Resharper (Ctl-Alt-F). Regioned code shows up in a box with an ‘x’ in the corner. You can use the ‘x’ to remove the region.

    Now, let it be said, that you’ve actually converted me on the whole regions thing. However, I do present one reason/argument as to why they might be useful: helping identify what members are part of what interface. In the learning environment I’m in, they like that. Colour pictures on my blog. :)

  • http://codebetter.com/blogs/kyle.baley Kyle Baley

    @Tomas: This is just the implementation for use whenever you want. Browbeating team members into submitting under my will is the topic for a future post. In preparation for that, I’d suggest you find yourself a big stick.

  • http://www.winterdom.com/weblog Tomas Restrepo

    I don’t love extensive use of regions, but I find careful use of them useful myself. Huh…. Isn’t a better option to simply disable outlining on VS for you instead of cramming down your dislike of regions on top of your other teammates who might find them useful? :)

  • http://codebetter.com/blogs/david_laribee/ Dave Laribee

    nice tips man.

    i am with you. regions are fugly.

    more fuel for the fire in the form of a shameless plug… http://laribee.com/blog/2007/07/22/why-regions-are-fugly/