#region. Sliced bread or sliced worms?


(editors note: Eric gave me several different options to use instead of sliced worms, but they were all less palatable. So to speak.)

Jeff Atwood wrote an interesting post on the use of #regions in code.

So, I thought I’d share my opinion. As somebody who’s was involved with C# development for a long time – and development in general for longer – it should be pretty easy to guess my opinion.

There will be a short intermission for you to write your answer down on a piece of paper. While you’re waiting, here are some kittens dancing

Wasn’t that great. No relation, btw.

So, for the most part, I agree with Jeff.

The problem that I have with regions is that people seem to be enamored with their use. I was recently reviewing some code that I hadn’t seen before, and it had the exact sort of region use that Jeff describes in the Log4Net project. Before I can read through the class, I have to open them all up and look at them. In that case, regions make it significantly harder for me to understand the code.

I’m reminded of a nice post written by C# compiler dev Peter Hallam, where he talks about how much time developers spend looking at existing code. I don’t like things that make that harder.

One other reason I don’t like regions is that they give you a misleading impression about how simple and well structured your code is. The pain of navigating through a large code file is a good reason to force you to do some refactoring.

When do I like them? Well, I think that if you have some generated code in part of a class, it’s okay to put it in a region. Or, if you have a large static table, you can put it in a region. Though in both cases I’d vote to put it in a separate file.

But, of course, I’m an old dog. Do you think regions are a new trick?


Comments (23)

  1. Miral says:

    I like using regions to wrap up a nested support class (or group of them), since it’s not really "important" to the general flow of the containing class.

    But I’ve seen some code that uses regions within method bodies, and to my mind that’s just evil and wrong.

  2. zzz says:

    Definitely annoying and simply a way to cover up problems that the IDE or language should manage better.

    XML comments should fold/hide themselves by default so you don’t need any region statements to hide them.

    A programming language of the future isn’t going to split stuff into some fragile text based class files. I feel it will work like some higher level IL style thing: you write code, then it gets immediately translated into "IL" which is stored in single or multiple binary files, no text files at all. When you open the "code" you actually always translate (disassemble) it from the binary to human readable. It could be conceptually organized in any way suitable to the domain.

    The closest thing that already does above I know of are video post processing tools that use nodes/graphs and maybe bit like IDAPro. So you kinda can zoom out of the code blocks to see the big graph picture of how everything connects. Similar to Spore game which allows to save the image of the create and the procedular code paramaters that create the creature into the png file, this future IDE/language saves the image of the "big picture" view of the graph and the code in same binary file.

  3. Chris Parnin says:

    Regions definitely made sense before partial classes to hide generated code.

    Many complaints on Atwood’s blogs stems from desires for the IDE to offer better support for making something automatically collapsible without needing regions.

    I wouldn’t count regions out.  Maybe future tools will be able to make use of them to include smart rendering:

    #region StateMachine

    switch(state) case x: …

    #endregion

    #region Math/Derivative

    #endregion

  4. zzz says:

    The IDE, language and the result to need become much, much closer together so when you are programming you are editing and seeing the end result – immediately! Think of creating levels in a game editor built into the game engine or painter painting. The moment you write the code and hit, if it’s ok, it takes effect and is immediately in the latest version of the binary. Version control, testing, specification etc is built into the system of course to kill problems errors before they get anywhere.

  5. RichB says:

    There are exceptions to the use of Regions (for example, I use Regions around #if blocks, which are, say, only used for debugging). But in general, Regions are a CodeSmell and I hope they are deprecated in C# v4.

    http://aspadvice.com/blogs/rbirkby/archive/2008/05/12/Code-Smells-in-C_2300_.aspx

  6. Jorge says:

    I think something isn’t bad per se just because you can do stupid things with it.

    Regions are useful sometimes. I don’t really like regioning the override section whereas I like to put all my constructors/finalizer inside a region (if there are more than one or two constructors). That holds the logic for initializing and finalizing the class.

    Again, I find it nice to differentiate interface implementations. If my class implements IRenderable and IMovable I think is great each one is in a different region as there’s a logic, a semantic meaning for each of them. So any time I can say "ok, I want to see how you move this object", I can unfold the IMovable implementation and look it up without being distracted by the rest of the code. And the same goes on with IRenderable or whatever.

    There are a lot more examples. Of course if you put a region everywhere or just put the same regions in every file without even considering if you should put them there, you have a problem, but it will be about not thinking, not about regions.

  7. Chris Nahr says:

    I love regions!  Yes, VS could and should automate their use, but they are great for organizing code files.

    I really don’t see how putting code in a different file is somehow less hassle than putting it in a region.  Look for file in project tree, double-click on file, Ctrl-Tab between files… that’s supposed to be less laborious than Ctrl-ML/MM or clicking on the Plus symbol within the file that’s already open?

    Or how exactly does not having regions facilitate reading code?  Do you guys only ever write one-line methods without XML comments?  In any code file of any length containing methods of any length, adding regions makes the file easier to read in my experience, not harder.  Easy to find another method, easy to simultaneously edit two methods in different locations, all without having to switch to a different outline window.

    Again, I understand that _typing_ regions can be a bit of a pain.  But reading them?  I think we definitely have a fine collection of "old dogs" here.  We know files but we don’t know regions, and we don’t like what we don’t know, eh? :p

  8. Stimul8d says:

    Okay,..i’ll be the fence-sitter here.  I do like using regions and they’ll usually end up being seperated into fields,props,public methods private methods,etc…  If it’s only myself working on a project, they go in a team i think some process needs agreeing on first so everyone can work to their best.

    What concerns me most about regions is that they exist in code.  Jeff writes "Why, exactly, are we writing code to accommodate the editor?" which is incorrect.  We write regions for ourselves, not the editor.  I can’t think of anything worse than allowing VS to infer regions.  However, if we could save regions as user persistent/shareable data in VS, THAT would be cool!  That said, with enhancements to the language such as automatic properties and object initialisers, much of that file-level separation won’t be needed.  

    I’ll still keep regioning off by access level i think simply because it makes a large class (which CAN exist without having to think about refactoring) easier to navigate and it’s all we have right now.  Regions serve a good purpose when used properly, same as most everything else.  

  9. Mike says:

    Like with pretty much any language feature #region can be and is abused.

    The worst use I saw is to hide a screen of code inside a function instead of just putting all that code in a separate function. Then there’s variuous "groupings" like by access type or by construct type (constructors, properties, methods) despite the fact that this "groupings" do not always reflect the logic/flow of the code. This kind of abuses usually leads to code that’s worse than "read-only", it’s "annoying-only".

    Tipically I put all (private) fields in a region, each nested class in its own region and somtimes interface implementations.

  10. Len Holgate says:

    Back in 2004 when I first reviewed some code that was full of #regions for a client I came up with these thoughts for why regions had arrived…

    http://www.lenholgate.com/archives/000400.html

    which included this … I guess I was a bit down on MS at the time 😉

    "Anyway, I can see why #Region might have been considered a good thing to design into the IDE given the way Microsoft love to push wizard generated code into places that you’re forced to also put user generated code (I know, it’ll be fixed in Whidby, ZZZzzz…). You can just see the dev meeting:

    Manager: That ‘forms thing’ demo you just did looked crap. The nice draggy drop stuff worked well but then when you went in to the code to add the single line of business logic code; you know, that "Hello World" thing, well, it was scary. There was all that other code you hadn’t written in there, how did that get in there? Why is it there? That will scare people.

    Dev: That’s all generated for us to make things easier. We could structure the code we generate so that the user never needs to edit the same code that we generate, but that’s very hard to get right…

    Manager: But it’s scary to see all of that code here in this demo. The people we demo to will hate us, can’t we put all that code in another file…

    Dev: Er, no, that’s on the list for the future, it’s one of the things we’re making crap so that we can crow about how we’re making the next version soooo much better by simply providing functionality that other languages have had since the beginning and touting it as a wonderful new invention…

    Manager: I see, good.

    Dev: We could add a hack to the editor…

    Manager: How long?

    Dev: 5 mins… We can add a #HereBeDragons directive. We could then enclose the generated code in a #HereBeDragons block and that will hide the scary code and just display "Here be dragons" in a pretty colour and nice font.

    Manager: Make the font user definable, and give them a pretty clicky thing to make it show the code…

    And then you let users define their own #Regions … "

    😉

    I guess a good fix would be a per user configuration setting which lets people decide to never have regions collapsed, ever. Then they just become ‘comments’ and I’d never have to worry about having to expand every file, every time…

  11. Kyralessa says:

    I like #regions if they’re used properly.

    Unfortunately, they almost never are.

    They should only be used for (a) code that should *never* be worked on (such as Designer code), or (b) code that should be worked on very, very infrequently (such as the "large static table" example you mentioned).

    When I see developers create regions for Constructors, Methods, Properties, Event Handlers, and the like, I get the impression that they don’t know how to use the outlining features of VS.  Which are, admittedly, cumbersome to use until you remap the keys.  I posted an example of how to remap them usefully on Jeff’s blog post.

    "I guess a good fix would be a per user configuration setting which lets people decide to never have regions collapsed, ever."

    YES!  I’d vote for that.  This would let the #region-addicted people continue to feed their addiction without having it annoy those of us who are more enlightened.  :)  The thing I hate about regions is that when you CollapseToDefinitions, the regions collapse too; there’s no way to collapse methods, properties, etc. without collapsing regions as well.

  12. cb says:

    Regions… should rarely be used.  What you said and I’m not that old :)

  13. Jay Bazuzi says:

    Hey, I get to take credit for making this situation marginally better.  I wrote a couple lines of code to switch on support for remembering the expansion state per file.  So, if you don’t like regions, and you expand all blocks when you open a file, then the next time they’ll all be open still.

    Personally, I believe that if your code overwhelms you when all regions are expanded, then you have some refactoring to do.

  14. Chris says:

    I once worked at a place where some manager had decided that method calls were evil (they were "too slow") and that instead of splitting large, complex method into smaller bites via methods the developers should instead use regions to "simplify" their code.

    This, of course, led to methods that were hundreds and hundreds (sometime thousands) of lines long with dozens of regions splitting up the various little bits. They were almost impossible to read and understand.

    It was pure evil. I have hated – hated – regions since then, and I actually tend to think less of people who use regions now.

  15. Len Holgate says:

    So, Jay, where do you store this state? Are you the one who’s made it that some of my source files don’t like being copied to drives that dont support extended attributes? Grrr.

    See here for more info http://www.lenholgate.com/archives/000785.html

  16. I’m on the fence as well.  I like using regions when I’m the only developer on a project (something I code for my own use).  Then I’m addicted to using them because they help organize code that I already know (and that no one else will change).

    I do like to pull properties out into a region, but that’s about it.

  17. Totally agree.  Refactor, don’t use regions!  Regions allow only one subjective, arbitrary and totally unverified classification.  Use first-class OO concepts to structure your code.

    This was my take on it:

    http://stuartharris4.blogspot.com/2008/06/c-regions-inline-comments-and-blank.html

  18. Craig Boland says:

    I’m a fan of regions and code folding for reasons that, according to reader posts, are the right ones (similar comment on Jeff Atwood’s post: http://www.codinghorror.com/blog/archives/001147.html). What concerns me are comments that regions and code folding should be deprecated because they hide crappy code. Crappy code is an indictment of the developer(s) that wrote it, not of the tool that organizes it. This is like firing the house cleaner because the house keeps getting dirty.

    #region as a code smell? I’m starting to smell a scapegoating bandwagon.

  19. John "Z-Bo" Zabroski says:

    As I said on Jeff Atwood’s blog, regions are a tool, and it depends how you use it.

    This is a bit like the false statement made by some that "computer science degrees are worthless if you want a software engineering job".  Computer science degrees are what you make of them.  They’re like tools.  In the hands of an oaf, they’re brittle because of the wielders proclivity for clumsiness.

    As I told Jeff, you should use regions to section off code generated by tools.  This is a best practice in model-driven software development.  If you aren’t looking at the models first, then you’re going to be spending way more time looking at the code.  If you don’t do model-driven development, then that takes away one of the biggest use cases for regions.  

    Yet, there are still other use cases for regions.  I also do use regions to section off code that is highly likely to be changed because it depends on interfaces that have yet to be frozen.  So, for instance, for Silverlight Beta 2 apps I am writing right now, I isolate hacks that I *know* are incompatibilities between WPF and Silverlight, and that I expect/hope the Silverlight team will fix by launch date (the Beijing Olympics).  I can’t write an #if WPF #endif #if Silverlight #endif block because I am deliberately trying to write Silverlight code, not WPF code.

  20. Jeno says:

    To Chris: Methods with hundreds and thousands of lines because method calls are too slow? I haven’t heard that before. The speed of a method call matters on methods with less than 20 or so lines, but on methods longer than that it is minor compared to the method’s execution time.

  21. Jsome says:

    To Jeno: read much? I interpreted Chris’ post as his manager was making that statement, not Chris.

  22. Michel Desangles says:

    Regions are great.

    While I’m working on a particular class (refactoring it, for instance, because I’m a Good Guy), I hate having 8 lines of usings, then a line break, then a namespace, then a curly brace, then the class name, then a curly brace, then 10 lines of private fields, then a line break, then a couple of events, then a line break, then the ctors, then a line break, and so on, take up a third of the height of my 19" screen.

    So, while working, I just region this out (into 2 or 3 regions, unfortunately you can’t region across logical code segments), so that everytime I ‘Page Up/Home’ in the editor, the main code starts almost at the top of the window.

    This is just a matter of screen footprint, I’m not advising to keep them forever, but while working on a file, it’s great to have around. And with ReSharper’s shortcuts, it’s a breeze to use.

    I vote sliced bread!

  23. Max says:

    regions are a bad thing.

    To Michel:

    Your use of regions is ridiculous, you’re mainly just showcasing your code out of context. Pointless.

    If you were one of my dev guys, your ears would be ringing.

    To all:

    Regions are sliced worms.

    I’ve seen too many developers use regions to hide code, and usually, it’s code that’s ugly.

    The only good use for a region was in .NET 1.1 and lower when you couldn’t use partial classes to move all your generated code to.

    Other than hiding generated code, regions are a very, very bad thing.

    I *hate* having to toggle all outlining when I open a source file because a developer went region galore. It wastes my time, and that of all other coders and maintainers.

    Furthermore, once the code is expanded, it’s even more difficult to read because of all those # starting lines.

    Code is here to be seen, if your code is so complicated that you need to hide sections of it, then resort to Helpers.