C# regions is a design smell



Regions feature in C# is frowned upon by many. There are good reasons for that. In this post, I’d like to discuss why exactly you should avoid using them.

C# regions on the class level

Regions are one of the strongest smells in the C# language in a sense that it’s hard to come up with a justification for their usage. If you see one in code, it’s almost always a sign of a bad design decision.

Let’s take a couple of examples. Here’s one of the most common use cases I see in which regions are involved:

C# regions design smell: Regions applied to a class

Regions applied to a class

It might seem compelling at first, especially if you are used to this style of programming. There are several problems here, however.

This style is often aimed to hide the fact that a class is too large and thus violates the Single Responsibility Principle. The problem here is that the use of regions doesn’t solve the underlying problem but rather amplifies it even more making it’s harder for programmers to see the issue. If there’s a problem with code, don’t hide it. State it. Make it explicit by removing the regions and try to solve it after that. The solution is often as simple as splitting the class into several ones.

One might argue that large classes are not the only use case for regions and that they can be applied to relatively small classes as well. Indeed, I saw code bases where regions were part of the code style and were used almost everywhere. It wasn’t unusual to expand a couple of folds and see that there’s effectively nothing inside:

C# regions design smell: Regions used as a coding standard

Regions used as a coding standard

So, would small classes be a good use case for them? No. While there are admittedly merits in such approach, one of them being a standardized code style, its drawbacks are much more substantial:

  • Regions hide the perspective. It’s hard to see what’s going on in the file you just opened. It requires you to take an additional action (unfold a region) which essentially results in poor user experience for developers.
  • Regions encourage programmers to group methods by their visibility and/or implementation details, not functionality. Of course, regions don’t entail such behavior per se but I see it a lot because, well, such segregation is easier to perform and standardize. It’s a good idea to group the class methods by their purpose even if it means you need to combine a property and a backing field or a public and a private method together. Such practice leads to better cohesion.
  • If not used for hiding large code chunks, regions don’t provide additional value and thus should be removed due to the Yagni principle. If a class is small enough, why even bother trying to hide different pieces of it?

C# regions on the method level

Although regions inside a method are less common, they sometimes take place as well. Let’s look at this example:

C# regions design smell: Regions applied to a method

Regions applied to a method

The problems with this method are essentially the same. In addition to sweeping the problem under the carpet, regions act as comments here. As any comments used inside a method, they signalize an issue with the code readability. Instead of hiding parts of the method under regions, it’s better to refactor it and extract the “Create an object”, “Perform an action” and “Save the object” portions into separate functions.

The “Parameter validation” part is a bit trickier. Large validation sections is a strong sign of primitive obsession. To solve this problem, create separate classes for notions in your domain model instead of using primitive types to represent those notions.

Any good use cases for C# regions?

Despite all said above, I personally think there are a couple of good use cases for regions in C#.

The first one is legacy code bases. It’s not always possible to break large classes into smaller ones when you work on a legacy project. At the same time, you may need to extend it in some way: fix bugs, add new functionality, etc. In this case, it would be probably a good idea to mark the “dark area” with several regions to help yourself orientate in it.

Another use case is some hack which you deliberately inject in your code. An example here would be email templates. If there are only a few of them and they don’t change often, it might be easier to just include the templates into C# code instead of using separate HTML files. If this is the case, you may employ regions to isolate the template text from the code.

It’s important to note that these use cases should be viewed as exceptional or, even better, temporary. They shouldn’t occur too often.

Summary

The biggest problem with C# regions is that they hide problems with code. If you see a region in your code, try to remove it and fix the underlying issue.

Share




  • http://methodicalprogrammer.com jeshan

    I agree with you. Especially with your point about “Regions encourage programmers to group methods by their visibility and/or implementation details”.

    Using regions to group by visibility: I think that should be supported by your IDE.

  • Kasper

    It’s a general thing with productivity features. ..they easily get in your way http://firstclassthoughts.co.uk/Articles/Readability/ProductivityFeaturesThatMayRuinCodeReadability.html

  • dasjestyr

    I think this post missed the mark. In fact, the smell here isn’t a smell; it’s what they were intended for. The smell is when people use regions to break up walls of code inside a single methods. THAT is a smell because it means you’re ignoring SRP. Large classes aren’t bad because they’re large. They’re only bad when they’re large because they violate SRP. If you have tons of properties in methods in the class that have nothing to do with the class (incoherent), then you have a problem. Sometimes classes are just large, and that’s when regions can help. Some people use them to group interface implementations, for instance. In fact, resharper offers it as an option. Making a blanket statement that large classes are a smell is naive and indicative of a misunderstanding of SOLID principles. There’s more to it than that…

    With regards to grouping by visibility/accessibility being a feature of the IDE, I can agree. But I see ZERO problem with using regions to sort them out. Even in small classes, the noise can become distracting and it can be helpful to collapse them inside of regions.

    I hate the argument that regions are code smells because they have nothing to do with code. Bad code is bad code, regions aren’t going to change that. If you see regions inside of methods, then that should look weird anyway, and that might be a smell and lead you to dig deeper. But the last thing the world needs is another developer that read some article on the net that made some asinine blanket statement like this and making it into a rule of thumb that no one ever really thought about.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Good point regarding SRP. Indeed, the underlying problem lies in a class violating SRP, not just being too large. However, I have a hard time remembering a large class not violating SRP.

      • dasjestyr

        Don’t get jaded, Vlad. That’s how good developers turn in to crap developers. I know you know this.

        • Joe C

          I’m with dasjestyr on this one. From my own experience I have always found them helpful. You fold a newspaper when you read it right (same thing to me)? Oh, you probably have a tablet. 🙂

        • thisisthelist

          I also completely agree with dasjestyr. One thing I have noticed more than once is when someone isn’t fond of Regions they point out the supposed downside as if it’s a fact, like water doesn’t pour upwards. Some people who code with excellence love Regions. And they will continue to use them.

  • John

    “It’s not always possible to break large classes into smaller ones when you work on a legacy project.”

    Why not?

    If regions are a design smell in new code, then code you’re unable to refactor is a design stinkbomb.

  • dirvo

    I think the smell here are not regions as such but the fact that VS decides to collapse regions by default. However, this can be remedied by the free “I hate #regions” extension (https://visualstudiogallery.msdn.microsoft.com/0ca60d35-1e02-43b7-bf59-ac7deb9afbca).

    Go and install that extension and this was the last time you ever worried about someone using regions.

  • Peter Brightman

    As compilers don’t need regions, nore tabs, cr/lf’s etc., any formatting should never be versioned or stored rather than created on-the-fly when a human views/edits code. Visual Studio already places nameless regions on namespaces, classes, methods, using statements etc. These are expanded by default, created on-the-fly just when some class is shown in the editor window and never stored along with that class or file. Imho, just the semantic part of a class should be stored and/or versioned. If some class should show up beautifully formatted in some editor – even by standardized formatting rules – this should be done in a non destructive way by applying the style rules at view time.