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!
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:
There’s gotta be something in that code there right? Something important!
So let’s open the region and have a look?
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:
Only to open the #region to see what’s inside and realise there’s nothing there!
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:
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?
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.