Stupid Question 44: Should I use regions in my code?
People like to organize and section of things, but should be even do that in code?
Let me start by saying that I don’t use regions in my code, I never did in the beginning and got used to not having regions. But many developers use regions, and I remember having a discussion with some fellow student when we were doing a group project as I was annoyed with the regions and he was annoyed for me not using them. During my internship I had the pleasure of working with a code base that was disastrous, code behind files spanning thousands and thousands of lines. Regions weren’t a bad thing there, especially since we had no time to refactor and had to find a way to live with the code. Today, I am very happy without regions and don’t mind a bit of a scroll if the code gets a little bit longer (although I do try to avoid that). SO my answer is:
I don’t use regions, I dislike them just as much as I dislike comments. With that said, sometimes a comment does serve a purpose, and sometimes regions can serve a purpose. But regions are best avoided if I can avoid them. With that said, sometime I probably will use them. But I shouldn’t need them (90% of the time- in an ideal world LOL), they probably will only make sense to me, and they give (for me) the impression of trying to ‘hide’ code. They fold it away. Like chucking stuff under the bed when cleaning, you can still pull it out, but it would be better if you had cleaned up properly instead, I’ve seen that a lot.
This is my thinking, based on what I’ve picked up from devs around me, and also heavily based on ‘feelings’. But I am very keen to hear what others think! And in particular when it is a good idea to use regions :)
Comments
Hi Dhaval! Thanks for the input! :) I'm not sure if I understand, do you group things in regions by functionality or type? I get the impression that you do both?- I haven't seen that before so it got me a bit curious (the combination) "I mainly use region for categorizing functionalities of the applications. Also I create region to have all events in one region.. all methods in one region.. all enums in one region, etc.."
I try to avoid regions. If regions are needed to make things clear, it is usually a sign that your class is too big. So in short, I agree with you :) Btw, I really like the analogy with chucking stuff under the bed :)
IMHO well written code generally shouldn't require regions. If code benefits from the use of regions then it's probably ugly code. In recent years I've learnt to adhere to SRP more and more and the vast majority of my .cs files tend to fit on a single screen, so why would I ever need regions? Of course there are always going to be exceptions, and I've heard people argue that when writing UI code with INotifyPropertyChanged and stuff then you simply can't avoid large files, which may then benefit from regions. I still think that in most cases, if SRP is followed to a high degree then regions still shouldn't really be needed.
IMHO, if you need regions, your code probably isn't structured very well. But having said that, there are times when you are forced into writing poorly structured code ... Like webforms for example. So with something like webforms, I might create regions around *functionality*. I will also put related fields, properties, methods, Etc.. into the functionality region, as opposed to the common properties/events/methods regions, but seems more logical to me. Naming regions properties/events/methods seems a little pointless. I suppose you could use partial classes instead of regions to separate functionality. But I avoid deviating that far from the norm to avoid confusion. I wrote a blog post about this a few years ago explaining my thoughts. If you're interested, it's at http://whileicompile.com/?p=370 and for the record, I no longer view a 300 LOC class a small class, but at the time it might've been considered relatively 'clean'.
I really think the use of regions depends on the situation. My company uses a BPM tool and every time you need to use c# code behind, everything needs to be within the same class. We use regions to collapse certain areas of that class and generic methods that we built. I will say, however, that overuse of regions actually make the code more confusing in my honest opinion. I also noticed that you hate comments. I think you should do a "stupid question" about that. I think comments are definitely useful and I use them frequently. I use them for my fellow developers so that they are better able to debug/modify my code if I am not available and be able to do it quickly. By the way, I really think your "stupid questions" are great. I think it sparks great conversations about coding and I bring some of these questions to my fellow developers to have discussion. -Harry
My question also, why so many lines of code in a single file? Why not categorize/separate you functionalities in multiple logical files or classes, except if you are working for Google :)
I use regions around member declarations (at the top of the class) and property declarations (at the bottom of the class). It's a nice tool to hide things away which don't have much to do with the logic to write in methods. I see you dislike comments. Don't. Comments can greatly help make code more readable. But of course you should write comments only when necessary: write a comment in/above pieces of code which are not directly clear. (For the reader who now thinks "but my code is always clear, if your code isn't clear enough, you're doing it wrong!", I'm happy your job is writing dull boring simple code everyone will understand! ;)). By explaining in simple comments why the call you make is made and at that spot, you make life easier when you come back to the code in say a year or so. Treat comments as part of your code though, so refactor them with your code. Personally I truly hate code which has no comments at all, yet is hard to understand. As if the developer has no intentions to maintain it. I maintain my own code on a project which I started back in 2002 and which is still active today. I learned the hard way that code which isn't properly commented is hard to maintain, even if you have written it yourself and you found it perfectly readable and clear from the get go. Finally, of course there are a tremendous amount of people who think they know better and will tell you to never use regions and never use comments because both are apparently a sign of weakness. If you enclose every method you write in regions, it might be a bit cumbersome to edit the code. But frankly, who gives a shit. If the code is maintainable, understandable, you achieved what many, including the haters, will probably never accomplish. Good luck :)
No never use them, if you using them then imo youd ouijng something you really shouldnt be, why do you want to hide code? If you use regions to structure code or to hide stuff like properties then why are you doing this? - to make it more readable, to fit on a page better perhaps - at the end of the day your hiding code and you shouldnt be doing that, you should be striving for less code by refactoring as much as possible, think of it like trying to minift your code - not putting it out of site. Regions are a code smell.
There are bound to be exceptions where regions will make sense. But I believe that when regions are used it is a code smell. In this case, that smell is due to having to lump everything in one class, which in turn is an issue with the BPM tool, and that is the root problem you are facing. The BPM tool shouldn't dictate such a thing and ought to be redesigned. But until that time, it seems like regions may sense for you.
IMHO if you are using webforms then regions are the least of your worries!
"It’s a nice tool to hide things away which don’t have much to do with the logic to write in methods." As I always say, regions are a code smell. If I were to pick up such a class, and expand the regions, the smell would intensify as I see these "things which don’t have much to do with the logic to write in methods". I would then ask why this type contains things which have little do with each other and probably recognise a distinct divergence from SRP. I'd then think about how to improve the model and consequently refactor towards some greater insight. At that point my type should no longer contain "things which don’t have much to do with the logic to write in methods" and my need for regions disappears... I have views on comments but I won't go into that here since it detracts from the topic - perhaps thats something to go into later in another post.
Use of regions should be restricted to tool generated code that is buried deep in your infrastructure. For hand written code, regions kill discoverability (especially when you're trying to remember what your code does when you're trying to fix that pesky bug 6 months from now) and often lead to bloated classes because they give you the illusion of tidiness. If you find yourself thinking "I should tuck this into a region" that's a pretty good indication that you're trying to do too much in your class. Instead, focusing on concepts like single responsibility in your class design will be of much greater value over the lifetime of your project.
In my humble opinion, regions where ok, when you implement interfaces from the .NET. Otherwise, the code should be as long it is possible to avoid regions. If you have a class with x regions and x-lines of code, then probably you should refactor the code :-) Greets Dan
Why should I use regions for members which inherit from an interface and not use regions for members which don't inherit from an interface?
I think regions are evil. Either they hide code, which implies the dev made something he didn't want other devs to see, or they are used to group chunks of code into single context groups. Like regions for fields, privates, protecteds and publics, etc. When I'm browsing for a method by name, I shouldn't need to know what it's accessibility is. Often when I see such code I drown in the regions and start feeling depressed. Nowadays I have my devs use The code cleanup tool from Resharper (oh, how I love that tool!), with my cleanup profile before checking code in. When they work their code they can use their own profile as they like best, but when they're done they'll have to strip all regions, sort by member type and alphabetically and indent properly. That said, the single only region I allow in my projects is the #region Generated Code. That's code you want to hide; you shouldn't edit it anyhow. But whenever possible that chunk should be in a separate partial class with a .generated.cs extension. I agree with you about the comments: there should be close to none necessary. Only todos, seemingly illogical code or complex mathematics should be commented. The rest should speak for itself.
For me - when working with XAML - regions are a necessity. A dependency property is a simple concept and just a collapsed region showing the name is enough to see what it is, but if you have 10-20 dependency properties and each of these consists of the static declaration, associated accessors, static change handler and instance change handler - it's beginning to get ugly. That said - I have worked with developers who would just not sit close to a region as well as ones who would praise you for well regionalized code. It depends on personal experiences, technologies you work with and how regions are used. It also depends on your screen size. If you are working on an HD 30'' monitor - you might be perfectly fine without them. If you have a 14'' laptop with lower resolution screen - scrolling through a 1000 line file is a pain. Of course there are tools to quickly navigate to a member and they work for some people, but they don't work for some. I would say - use what works for you and respect other people's opinions. Focus on the goals instead of the means.
Agree with the DependencyProperty stuff. I forgot to mention that. DPs are a great concept but they clutter code horribly. To get aroud this, I created a DependencyProperty generator that lets me define the properties, RoutedCommands and all related handlers from a single clean XML into a generated partial class. That way I keep things clean and readable.
Like comments, regions should only be used when absolutely necessary. There will be a case once in a very long while where you can use it without a fuss. However, overall it just makes the code muddy. If you need to use regions to separate functionality you NEED to refactor. What you get is clean elegant structure and not a confusing blob of code in a file that makes you want to scream out, WHY!!!!!!!!!!!! Keep it up Iris! Lovin' it!
I agree with most of this post. Regions should not be used to make up for poorly structured code. That being said I use them for two things. 1. Grouping properties together at the top of my classes. Once the class is has evolved enough, I rarely touch the properties anymore so I want them out of the way. I can't bring myself to having properties at the bottom of my class so regions collapses them neatly out of the way. 2. Webforms. Webforms seem to force giant classes. Keeping all logic out of the codebehind and in proper business object still leaves quite a bit in the codebehind classes. I use the following regions in webforms codebehind classes only. Properties Page Life Cycle(page load, prerender, etc..) Render Events(databinding events) User Events(button click, onselect events etc..) Just like anything else in programming ,there's always a way to misuse a language construct or IDE feature. Nothing makes up for good practices and judgement.
In my company there is a standard of grouping code and using regions like fields/private variables, public properties, public methods, private methods, etc. that I'm not really fond of. I don't find it helpful and prefer not to use regions. Sadly my colleagues are rather attached to this practice so it is likely to stay.
Like I said, around property declarations and members, regions are IMHO a must. How are you going to refactor those away? It's all about making you focus on what you have to do. Regions can make you focus more on the code you have to write (by hiding what's not important _at that moment_, like property declarations and member mess). I don't see how you'd do without properties/members ;)
@Steve Crane: look into Resharper's code-cleanup. It's tough to setup, but then it's just ctrl-e-c and all is done. Regions created or removed, methods sorted or not, interfaces regioned or not, "this." or "base." added or stripped, "var"s introduced or replaced, etc. etc.
Repeat after me: CODE REGIONS INDICATE SMELLY CODE! They indicate that your class is not yet decomposed properly. Decompose your class until the code regions are unneeded.
Unless it is strictly mandated, don't do it in any new code you write, Steve. Do what you can to help the practice die out gracefully.
As per my previous comment, if you have to use regions to "focus on what you have to do" and "hide what’s not important _at that moment_" then this suggests that the type has too many responsibilities and needs to be refactored. I tend to judge a type as being well-written/refactored when every bit of code it contains is important and relevant to every other bit of code it contains.
Oh dear.... sounds like a classic case of cargo cult programming. Perhaps you can persuade your colleagues to read this post and the comments?
We do use Resharper but haven't gone beyond the default rules. Some developers refuse to use it, saying "It slows Visual Studio down too much". We can't even get all our developers to set their VS to use tabs instead of spaces for indenting, even thought that's what our coding standards (guidelines really) say should be used. There's little chance of us agreeing on a set of Resharper rules and getting all our developers to use it, unless by management decree.
I can't live without R# anymore. I try it once in a while: plain VS without extensions, it drives me crazy. You could always make your own cleanup profile and one matching corporate standards. Check out, clean to your profile, do your stuff, clean to corporate profile, check in. You wouldn't need consensus on the profile, and could still make life easier. Some of my devs do (or did) it like that the other way around. Having personal profiles with regions and fully specified types and no this operators. And the clean uniform minimalistic corporate profile before checkin in.
(totally off-topic: is it me, or did the posts of Simone travel back in time about 8 hours? I don't recall seeing them earlier and according to the notifications they were added after my last post, but they are 8h back in the thread...)
Wow, you really know how to start a fight, don't you? ;) I'm odd. I think regions are very useful. But with great usefulness, comes great responsibility. I think it's generally a mistake to put everything into a region, but it's very good to hide boilerplate code which serves to distract from the real purpose of a class - things like lists of fields, constructors that just check parameters and assign to readonly fields, Dispose methods, and low-level helper methods. If you've got an editor that collapses regions for you when you open up a source file, then you can be left with just the important bits of a class being visible: the public methods and properties. This is good; it allows the maintenance developer that follows you (i.e. *you* in six months time) to see the important bits of your code without all of the distractions of the implementation details.
To be the iconoclast here, I like regions. I like the ability to fold up unrelated code, and see just what I'm working on. Get back to Iris's original comment on the matter: "Like chucking stuff under the bed when cleaning, you can still pull it out, but it would be better if you had cleaned up properly instead" Continuing that analogy, not using regions would be like throwing out your broom, on the premise that it's only good for sweeping thing under the bed. If you want to clean things up properly, then that could be done with proper use of regions. Code without regions would be like having your clothes strewn about the house.
"not using regions would be like throwing out your broom, on the premise that it’s only good for sweeping thing under the bed" - I couldn't agree more. That, generally, is all regions are good for. "If you want to clean things up properly, then that could be done with proper use of regions" - to clean things properly is to tackle the problem head on and refactor the code until it is well organised. On the contrary, using regions is avoiding the problem by, I will say it again, sweeping it under the carpet, and pretending it's not there. Is it better to actually have organised code through responsibility segregation or to have an illusion of organised code through regions?
Last modified on 2012-09-14