C#: Should we still use #region blocks? My two cents about StyleCop's SA1124 "DoNotUseRegions" rule and why I still (rarely) use #region blocks

Classe ASP.NET C# per il controllo e il calcolo formale del Codice Fiscale

In this post we'll talk about #region blocks, the C# preprocessor directives that let the developer specify a block of code that can be expanded or collapsed when using the outlining feature of the code editor.

Here's a quick example to understand what we're talking about:

For additional info about C# regions and common usage samples, read the offical guide from Microsoft Docs.

Regions were introduced with the first versions of C# and were praised during the language's early years because they were seen as a viable technique to improve the code readability, especially in long and complex classes. However, they can also lure the developer into adopting a number of bad practices, such as shoving "unoptimized" or repeating code to hide it from view instead of refactoring it; dividing a complex method (or class) into multiple "tasks" instead of splitting it into multiple methods (or classes); embedding redundant code instead of making it less redundant; and so on.

Since the potential disadvantages of regions vastly exceed their supposed advantages, regions are now considered a bad practice by most C# developers and their usage has declined. This opinion has been enforced by StyleCop, a great open-source static code analysis tool from Microsoft that checks C# code for conformance to the recommended coding styles and design guidelines, which summarizes its judgment regarding regions in its SA1124 rule:

TYPE: SA1124DoNotUseRegions
CAUSE: The C# code contains a region.
DESCRIPTION: A violation of this rule occurs whenever a region is placed anywhere within the code. In many editors, including Visual Studio, the region will appear collapsed by default, hiding the code within the region. It is generally a bad practice to hide code, as this can lead to bad decisions as the code is maintained over time.
HOW TO FIX: To fix a violation of this rule, remove the region from the code.

This kind of settles it: we should never use region blocks, period.

Those who want to know more about the #regions debate within the C# developer community and the reasons why they are discouraged nowadays might enjoy reading this Stack Overflow thread, which pretty much summarizes it: again, the verdict was (almost) unanimous: region blocks = code smell, and the best thing you can do to avoid such smell is open the window - and throw regions away.

Although I generally agree with this generalized "anti-region" approach, I also think that using #regions to group together fields, properties, and so on can still be useful in some edge-case scenarios, such as code samples and tutorials (like my ASP.NET Core and Angular book series), because it allows us to distinguish between different parts of code: for example, we're going to use them to help the reader tell apart standard properties versus navigation properties within an entity type.

This is why I'm still using them here and there, even if I'm fully aware that a good, StyleCop-compliant code won't need them - not even to group together fields, properties, private methods, constructors, and so on: at the same time, I also recommend not using them (or limiting their usage to a minimum amount) in your actual code.


About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

One Comment on “C#: Should we still use #region blocks? My two cents about StyleCop's SA1124 "DoNotUseRegions" rule and why I still (rarely) use #region blocks

  1. Ryan, I agree with you. I just told my team not to use #region anymore, then I started building an httpClient library project for our upcoming projects, and found myself wanting to use #region to separate the private and public methods in the default httpClient wrapper because it started getting a little big, and I was like oh boy have to make exceptions maybe! thanks for this post!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.