The Anti-Region Campaign

For the benefit of my twitter followers who know I have an ongoing issue with the abuse of #regions in the code I have to work with, let me take some time to explain why I dislike them so much.  In fact, let this be considered yet another step in my ongoing anti-#region campaign! (similar to the anti-if campaign)

This is not to say #regions aren’t useful, but that they are far too over used, and until people can consume #regions responsibly, prohibition laws should be enacted.

Got an Opinion? O‘course You Do!

Even without reading this post in full I’m sure you already have an opinion and like most people on internet time you’re likely to skim the first paragraph or two and then skip the rest, so to save you time here’s how to leave feedback:

If You Agree with Richard: If you too dislike the abuse of #regions then leave a comment on this post. If there’s enough support I might think about starting a proper anti-region campaign.

If You Think Richard is a Raving Lunatic: If you think I’m over-reacting, slightly unhinged, don’t understand your special needs and why #regions make the world around you glow, or if you count yourself as a #region lover then I would ask that you leave your comments and feedback on this post here instead.

Why Do #Regions Even Exist?

So why in the name of all things good and holy, do #regions exist in the first place?  Don’t they kill kittens?  Aren’t they pure evil?

Let’s have a look at what the MSDN documentation says, shall we?

#region lets you specify a block of code that you can expand or collapse when using the outlining feature of the Visual Studio Code Editor. In longer code files, it is convenient to be able to collapse or hide one or more regions so that you can focus on the part of the file that you are currently working on.

OK.  That seems nice on the surface, but isn’t the code I’m working on a class file?  Don’t I need to see it in context? Hmm.  Let’s have a look at the reasons I don’t like #regions shall we:

Reason 1 – It Hides Code

So, according the the spec, it’s to hide chunks of code to help us focus more on the bits we’re changing.  Do you see the problem with that?  Why would I, as a developer, want to actually see code?  Are you out of your mind!  Code is the last thing I want to see!  I want to write code, not read it!

I should be able to look at a piece of class and get an understanding of it straight away and how it fits in with the rest of the class.  #regions can prevent that from happening.

How can I actually tell what this code is doing? And apologies for the Hungarian notation VB code – I hope it doesn’t burn your eyes too badly!

image

I know there’s something going on in there (the line numbers give me a hint), but can I know at first glance what it is? No chance!  This is a bad thing.

P.S. One valid reason to allow #regions to exist is designer/code generated code.  However the availability of partial classes since Visual Studio 2005 means that a we’ve been able to pull all that designer generated crap out and keep it in a separate file for a long time now.  There’s no need to have that junk cluttering up my own hand crafted junk! #regions are redundant in this case.

Reason 2 – It Hides What You Think Might Be Code

I just love seeing this sort of thing:

image

There’s gotta be something in that code there right?  Something important!

So let’s open the region and have a look?

image

Say what!? There’s nothing useful there at all?! It’s just commented out code?

So the #region is “helping” us by hiding commented out code!  Surely I don’t need a region to help hide that from me, do I?  NO! Just delete the code! Don’t comment it out and wrap it in a #region!  What a great way to waste my time!

Reason 3 – It Hides Nothing At All

I don’t know wether to blame horrible coding standard that mandate the presence of specially names regions for segment class files or not but I’m sure you’ve never seen this little gem:

image

Only to open the #region to see what’s inside and realise there’s nothing there!

image

It’s like being given an empty box for your birthday.  All nicely wrapped up and making you wonder what special surprise is hiding inside only to open it and find that your kid brother has been playing a horrible, cruel joke on you.

What’s even better is when you see a class with all the mandatory regions in it (like the code we saw in Reason 1) and yet when you open all the regions up, there’s just a single static method in there and the rest is blank. Or even better, the whole class is empty!

Regions like this fail completely in their mission to help you focus on just the code you need to see, and instead add only noise and confusion to the understanding-what-the-class-does process, and make you doubt any other #regions you see elsewhere in the codebase.

Reason 4 – It Hides Just One Thing

What about this #region:

image

There’s going to be some really complex code in there, right?  Why else would I have a region there, especially since regions are meant to hide code that might distract me!

Open it up and what do I see?

image

Oh wow! Just as well we used a region to hide a single property!

Again, we’ve added noise to our code base for no reason.

Reason 5 – It Hides Butt-Ugly Code

So what about this situation?  You’re looking through a code base and see the method from hell and it’s associated demonic friends.  We don’t want to see that code do we?  No way! We want to hide that complexity, so let’s wrap it up in a region! Great thinking!

This is what we are really doing with our code: We’re sweeping all that ugly under the carpet.

As a general principle, classes should have a single responsibility and methods should be 20 lines of code or less so they stay readable.  If methods are longer than that then you’re likely working at multiple levels of abstraction in the one method or trying to do too much, and you should consider refactoring your code to improve it’s design and readability.

It’s better to keep the ugly visible so that you can deal with it.  Hiding bad code behind regions only serves to make bad code acceptable and it discourages efforts for improving it.

Reason 6 – It Hides Copy/Paste Efforts

The DRY principle means logic should exist in one place and one place only, not be repeated all over the place, because a change to the logic means finding all the spots that logic exists and fixing them all.  It’s much easier to make a fix once than it is to fix it in multiple places.

If I have a code base covered in regions I can’t tell if one section of code is similar to any other code I’ve seen before, because in all likelihood I’ve not seen it!  It’s probably been hidden away behind #region statements that mask all of the complexity and character of the code, instead making it a big block of beige.

Here’s what code looks like when #regions have been liberally applied to it:

It all looks the same.  And you’re not sure if it’s laughing at you or about to turn on you!

What About Grouping Your Code?

Let’s say you think #regions are great because they allow you to group your code and hide all those messy internal field and property declarations.  If you’ve only got a handful of them, do you really need the #region?  Probably not.  There’s not much to hide.

If you’ve got hundreds of the suckers do you need a #region?  Maybe – though at that point you should be considering the design of your system.  Do you really need a class with that many properties or fields?  Can you alter the design to improve things? Is your class doing too much?  That’s a judgment call you’ll have to make.

My gripe is with #regions is not with the directive in and of itself, but with it’s abuse.  If a #region is being used as I’ve outlined in the reasons above, then it’s time to stop, think about your code and why you’re using a #region and to then do yourself a favour.  Remove the #region and start writing better code instead.

That will be all.

 

Reader Comments

Regions are a signal that your code is poorly structured and that you're trying to cope with IDE tricks. Code readability is best improved by proper structure.

If you group elements by type (fields, properties etc)you are ignoring that they're interrelated and thinking too much about the implementation concerns and not the actual purpose of your type.

If you have enough code in a file to warrant a region the solution is to extract the code into smaller, more understandable bits (e.g. extract class refactoring).

I agree with you that region misuse it bad, but disagree that regions aren't evil and can be used correctly. The only winning move with regions is not to play. :P

Regards,
A fellow raving lunatic

Regions are great for identifying junior developers who are otherwise referred to as senior.

I think the best use of regions I've seen (and use) is for wrapping author comments/OSS licence(s) at the start of a file.

That kind of info should not be in the code. Licence file at the project base, author comments in source control. Otherwise it's just noise as is demonstrated by the need for a region to hide it.

Obviously some places have policies that require it. Those policies are wrong.

So if this gets off the ground do we partition JetBrains to add "remove regions" as a code cleanup option in ReSharper?

I agree with those much smarter commenters in the past, but will give my point anyway.

Regions aren't bad. The way people use regions is bad.

On one hand we advocate not mollycoddling everyone with the framework, we want more power, we don't want abstractions that prevent us from doing useful things, sealed classes, and only the Microsoft way.

On the other hand we can't handle our own code management because we obfuscate and hide blocks of code, reducing their meaning and importance?

You said it yourself, "This is not to say #regions aren’t useful, but that they are far too over used" - regions are useful, so let's not eliminate them, but train users to use them more responsibly.

Your point 4 is kind of hilarious given the user can use Visual Studio to change the [-] beside the code itself to reduce the code to the signature itself, and the use of regions is redundant, given you're not saving yourself space, but you're hiding more information that would show the importance of the code, reduced.

As others have said, it's a sign of something that should probably be refactored to smaller, more managable classes and/or to reusable code.

Regions aren't bad, developers are bad.

"Guns don't kill people. Bullets kill people."?

@Colin, agree completely. I don't use them for personal stuff. The main point I was trying to make is that the best use I've seen is for file content that is not code, which according to MSDN is not what they're for.

I think it's a bit like the "guns don't kill people, people kill people" argument (bear with me) - some of the reasons you give such as hiding single implementations or ugly code are faults with either the code itself or the way the region feature is being used. It's not that the region syntax itself is evil.

At the risk of being outspoken - and to be clear, I'm not a region proponent - there is some upside to the use of regions in that it *can* illustrates thought has gone into the logical order or grouping of code. Sure, single responsibility and separation of concerns and all that, I'm just saying I often see it approached with a degree of structure, just not the type we'd ideally like.

Another mitigation to the region scenario is that for folks running ReSharper, at least the contents are exposed via the File Explorer window. Sure, not the whole code but you get a good idea of what's going on in a single glance which would otherwise hidden in the collapsed region.

As for collapsing bucket loads of code, well of course that's available in the IDE anyway via the little plus icon (albeit it not across multiple structures), so the "hiding one thing" use is really pretty redundant.

Bottom line; I'm not in favour of regions, but I also don't think they're the devil's spawn! SOLID and DRY and all the good stuff will lead people away from regions naturally, just go easy on the practitioners in the interim :)

Agree. I would add one more exception to the rule which is mock classes in tests where a mocking framework can't be used.

#region Indifferent about regions

All of your reasons are due to stuff being hidden...

Ctrl+M,L == 'The magic cure for region pain'

#endregion

@Mark,

Ctrl+M,L doesn't help change the fact there was so much code in the file the dev felt it necessary to use #regions. ;) :P

Recently I've used code regions to group together and sweep under the carpet a bunch of deprecated methods in a file. I don't want people using these methods and have attributed them with ObsoleteAttribute and so to clean up my view of the code until the next release when I can delete said methods I've wrapped them up in a code region at the bottom of the file. I reckon that's a pretty reasonable use of region.

Ceterum censeo regionem esse delendam.

If you *really* feel you need to hide some code (extremely long declarative stuff, f.ex), put it in another partial of the same class.

Regions are mostly very annoying. Quite often coders put things in them that don't relate to the region.

regions around Interface implementations would be the only time I would use them and that is because VS creates them.

I think all of your arguments are based on bad programmer practices, not usage of region statements.

Region statements produced with static analysis (such as auto generated by Resharper) allow you to group your code into a very convention standard layout in your file.

So I am strongly in favor of using a tool like Resharper to enforce code layout style and to group similar members, fields, ctors into respective regions. This is the pattern I have implemented for my shop.

All of those issues can be solved easily with this extension: http://teamsearchapp.com/region-tool

It auto expands the regions and makes the #region/#end region lines less noticeable.

...

And there I was thinking I was the only person intolerant enough, thank you all :-)

As I type write now, I'm looking at a codebase in the other monitor that has some of the worse uses of region I've ever seen. #regions hiding copy/paste code instead of refactoring to methods, #regions for each interface, properties #regions, public #regions, private #regions, constructor #regions (mainly empty), they are all there. (Oh and two partial class definitions in the same file, but I digress).

Now I could live with them except I have a habit of using Ctrl-M,O Collpase to defintions, and everytime I do that my regions collapse again. For me this is where I think that regions are broken, that there is no good use for them at all...

I can only agree with any other reason from this list you have provided here in this post of yours. Everything is clear and logical to me. Thank you for sharing your opinion on this, that was very nice to read this post.
Evan Hammond, fan of internet radio

Hmm, I disagree, I like regions in that they 'clean' up the class. I agree with your statements that the regions described in your article are bad, but if we were to start removing things from languages because they were misused we wouldnt have many things left to program with.

Not sure why Toggle Outlining is so hard to click to expand all regions.

So your running an anti-region campaign for your own personal gain because you find it inconvenient ?

Instead of anti-region how about, "pro-help with regions campaign" =)

This would be the same as anti do while , anti for, anti thread.Sleep.

All used incorrectly can cause issues!

Post a Comment



Welcome

Thanks for dropping by. Enjoy your visit!

MVP Logo Visual Studio 2012 Cookbook
Find out more about Richard.

Richard on Twitter  
profile for Richard Banks on Stack Exchange, a network of free, community-driven Q&A sites

User Groups

My Open Source Projects

Podcast

Blog Archive