Regions == Evil

I had an email thread at work with a bunch of the guys on regions and this is the concensus we generally have come to (some of the statements are theirs, not mine, just paraphrased here). I was once a convert who liked regions. I enjoyed them. They made me happy. In all the code I would do something like this:

class UserCondition : IActionCondition

{

    #region Fields

 

    private int _condition;

 

    #endregion

 

    #region Constructors

 

    public UserCondition(int _condition)

    {

        this._condition = _condition;

    }

 

    #endregion

 

    #region Properties

 

    public int Condition

    {

        get { return _condition; }

        set { _condition = value; }

    }

 

    #endregion

 

    #region Public Methods

 

    public bool CanExecute(string action, WorkItem context, object caller, object target)

    {

        string userName = Thread.CurrentPrincipal.Identity.Name;

        return userName.ToLower().Equals("domain\\joeuser");

    }

 

    #endregion

}

That felt good and organized and neat (almost in an OCD way).

However I have seen the errors of my ways, as others have before me. Regions are evil. Pure and simple. The absolute incarnate concentrated type of evil that only the Time Bandits would fear and not the watered down, garden variety kind of evil.

They're great for hiding the annoying details of an IConvertible implementation or designer generated code (when it's not already in a partial class). But I often create methods on the fly using ReSharper and it is not going to look for the correct region to place the method. So having everything separated into regions actually slows me down because I have to find where to put the method.

ReSharper is your friend. Ctrl+F12 is all you need to find stuff in a file. Using ReSharper's type member layout to enforce code layout in a file, you can get consistency across all teams so one code file isn't vastly differently organized (say that 3 times fast) than any other project. With the custom pattern on, formatting puts all the members in all the right places and keeps layout and code style somewhat consistent across teams. It makes diff comparisons and merging a more pleasant experience.
 
Going forward, we're purging them from all projects and forbade use of them in new code. YMMV.

18 Comments

  • Oh man, I _hate_ #regions!

    They are cruft from the days before there were partial classes when the Visual Studio team tried unsuccessfully to hide the implementation details of their designer serialization hack from programmers.

    It makes me ill to think of how Visual Studio would badly mangle or even destroy Windows Forms designer code because of this ridiculous hack back in .NET 1.x days.

    #region sucks!

  • I've always felt that regions break collapse to definitions.
    I battled what I called "the seven magical regions" for quite some time. Aside from the difficulty of separating "Methods" from "Overrides" using the same regions makes all classes look the same ;)

    When you can collapse to definitions (I've mapped it to CTRL+D ) the only time I've found that a region increases readability is when you have a method with a bunch of overloaded version.


  • CTRL M-O is your friend, minimzes everything.

    I like regions... but within reason. Whoever wrote that code snippet above needs to be smacked around with a live tuna!

  • In general I agree - if used consistently, as you describe, they are a bit smelly. I do like using them to hide code when, if you you look at a the region name, you know what's inside it. It helps readability a little when we don't have a good metaprogramming facility. Like this:

    #region dependencyproperty int MyProperty
    //// dependency property boilerplate
    #endregion

    I've actually updated by propdp snippet to include that by default.

  • Agree.
    I don't know a case where I would use #region. We have mechanisms how to reorganize a code to be much more readable: split class to separate classes, use partial classes, use method instead big chunk of code wrapped by #region. I also agree that there are cases where #region is a “Code Smell”.

    You've got "kick" from me.

  • You use ReSharper and don't know how to manage your regions? Menu ReSharper, Windows, File Structure Window ... and all your troubles are gone!

  • what are you? retarted?
    "I have to find where to put the method." ???
    tool called Regionerate, man...

  • Regions exist for people that cannot do proper seperation of responsibility.

    Lots of regions almost always refer to bad code.

  • Agreed! I find them an additional and annoying overhead. Keep your code neat and tidy yes, regions (especially nested ones) are simply evil!! I do like to use them for certain grouping especially the 'Interface Implementation' style but on the whole they add overhead, not value.
    That raises another issue... the code comments that add no value but double the amount of code! ;-)

  • I don't think I would say "regions are a code smell". Depends on how you use them.

    That being said, our favourite hillbilly has converted me into the "you-don't-really-need-regions" crowd. I've stripped all the regions out of my R# templates, and as I find them in code I remove them. I find stuff much faster with the various R# enhancements.

    I notice a while back in R# 3.0 that R# has a Options..Languages C#...Type Member Layout. In here it looks like you can specify the rules to apply when you use R# to reformat your code. I was thinking when I have some free time (on the 9th day of the week) to create my own set of rules to strip out regions.

  • It would seem the title should be "Regions == Evil if you use Resharper and spend more time writing code than reading it"

    [)amien

  • I find it completely stupid to separate members of a class by kind. I know that's a constructor, a property or a method, besides I've already sorted them in the order: fields, constructors, Dispose/Finalize, properties, public methods, internal methods, protected methods, interface implementations, private methods. (or thereabouts depending on the logical relations between the declarations)

    I always disable code folding. I simply have no interest in expanding regions as I read through a chunk of code: I'll miss stuff. It's sometimes hard to say which details I skim over will turn out to be relevant.

    I'm not afraid of a thousand line file if it's well structured. Seeing it all is a sign that there's room for improvement. Occasionally regions are useful in a class with a lot of behavior (like MbUnit Assert) but they can be a code smell too.

    More importantly, I treat regions as a coder smell. Lots of regions tells me that either a coder is OCD or has difficulty reading and making sense of modest volumes of code. The same symptoms will often show up in the design. I use this information to my advantage when acting as a mentor.

    IMHO, regions a poor substitute for what Visual Studio should have had to begin with: a decent outline view.

  • I happily use regions in my classes, but only to keep the properties/members separate. It helps, I think, to keep them out of the way, and you can always easily find them. Anything in moderation can be good :)

  • I agree with [)amien -- you've artificially lumped a problem with ReSharper onto C# and argued its all C#'s fault.

    All the arguments against regions seem to be that regions hide the code from you. Regions don't hide anything from you, the IDE does. This is like syntax highlighting; if you don't like it tell the IDE to not fold.

    No one here has pointed out any actual flaw with regions. Everyone has tried to argue that their personal opinion is somehow "true".

    ARKBAN

  • IMHO, regions are decreasing discoverability of the code and makes code reading much harder
    I would use maybe regions only to hide non sigle type field declarations and private helper methods (to reduce the code noise)

    In general, I was using regionerate but my personal experience is that putting public memebers in region makes things worst.

    Offcourse, R# rules! :)

  • If we touch it will we blow up like the parents who were warned? :)

  • Oh my, anyone who flat out thinks "regions" are evil does not know how to program correctly and does not know what they are talking about. What about constructor overrides ? You don't put those in a seperate file, but do you really want to see 5 or 6 overrides all the time, no, put them in a region. Same goes with abstract, virtual, protected methods etc., wait, you guys do use these right?

    Putting regions all over the place for the sake of it is of course bad, but in the correct context they are extremely useful.

    Equally, if a class had that many methods putting them in seperate files is not an answer, the answer would be to refactor like methods into more loosely coupled classes/files.

    And how does it make code hard to read? If you're that bothered expand them all, read, then collapse, if not do this properly and STEP THROUGH your code (you do know about the F10/11 keys??) To try and understand code without stepping through it first is another "newbie" mistake - get some experience before you make such ridiculous comments.

    At the end of the day if you have time to worry this much about regions you probably do not spend enough time on your requirements/testing/coding. Regions don't break code, poor design does. Worry more about your design.

  • Nobody said that the regions have to be called Constructors/Variables/Properties/Methods etc. I use regions to group 'units of work' - several methods that each have one purpose but ultimately perform one 'larger' action as defined by the application.

    Take generation of a PDF report - I might have to gather data from several places, pass it to SSRS to generate a report, export it to PDF format and save to disk, and append two further PDF documents to produce one report file.

    If my unit tests found a problem with the 'unit of work' I would quickly be able to find all other methods which contribute to the functionality of the 'unit of work' and correct the problem.

    As David said - #regions don't break code, poor design does. If you worried about your design more, you would realise the use for regions.

Comments have been disabled for this content.