C# – Why Are People Opposed to #Region Tags in Methods?

ccoding-style

I hear a lot about keeping methods short and I've heard a lot of programmers say that using #region tags within a method is a sure sign that it is too long and should be refactored into multiple methods. However, it seems to me that there are many cases where separating code with #region tags within a method is the superior solution to refactoring into multiple methods.

Suppose we have a method whose computation can be separated into three rather distinct phases. Furthermore, each of these stages is only relevant to the computation for this method, and so extracting them into new methods gains us no code reuse. What, then, are the benefits of extracting each phase into it's own method? As far as I can tell, all we gain is some readability and a separate variable scope for each phase (which will help prevent modifications of a particular phase from accidentally breaking another phase).

However, both of these can be achieved without extracting each phase into its own method. Region tags allow us to collapse the code into a form which is just as readable (with the added benefit that we no longer have to leave our place in this file should we decide to expand and examine the code), and simply wrapping each phase in {} creates its own scope to work with.

The benefit to doing it this way is that we don't pollute the class level scope with three methods which are actually only relevant to the inner workings of a fourth method. Immediately refactoring a long method into a series of short methods seems to me to be the code-reuse equivalent to premature optimization; you are introducing extra complexity in order to address a problem which in many cases never arises. You can always extract one of the phases into its own method later should the opportunity for code reuse arise.

Thoughts?

Best Answer

All you should ever care about is for your code to be usable, not reusable. A monkey can transform usable code to reusable code, if there are any transformations to be done at all.

The argument "I need this only here" is poor, to put it politely. The technique you're describing is often referred to as the headlines technique and is generally frowned upon.

  1. You can't test regions, but you can test true methods in isolation.
  2. Regions are comments, not syntactic elements. In the worst case the nesting of your regions and your blocks contradict each other. You should always strive to represent the semantics of your structure with the syntactic elements of the language you are using.
  3. After refactoring to methods, one no longer needs folding to read the text. One might be looking at source code in any tool that doesn't have folding, like a terminal, a mail client, a web-view for your VCS or a diff-viewer.
  4. After refactoring to methods, the resulting method is at least as good as with regions, plus it is simpler to move the individual parts around.
  5. The Single Responsibility Principle suggests that any unit should have one task and one task only. The task of the "main" method is to compose the "helper" methods to get the desired result. The "helper" methods solve a discrete, simple problem in isolation. The class containing all these methods should also only fulfill one task and only contain the methods related to that task. So the helper methods either belong into the class scope, or the code shouldn't be in the class in the first place, but at least in some global method or, better yet, should be injected.

Also relevant: Jeff Atwoods's thoughts on code folding