#regionを使わないほうがよい３つの理由と１つの例外

# #regionとは何

&#35;regionは、IDE(VisualStudio)上でコードを折りたたむための機能です。
以下のようなコードを書くと、

```HogeForm.cs
public class HogeForm : Form
{
    #region Member variables
    private string _currentStatus = "";
    private bool _isInitialized = false;
    #endregion

    #region Constructor
    public HogeForm()
    {
        InitializeComponent();
    }
    #endregion

    #region Event Handlers
    public void Hoge_Load()
    {
        // Process something
    }
    #endregion
}
```
VisualStudio上では下図のようにコードが折りたたまれます。
&#35;regionはクラス内のメンバの分類や、メソッド内の処理の区切りとして、コードの可読性を上げるために使用されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212876/535a3162-2d63-6245-cdf3-6129d8963f5b.png)



# 使わないほうがいい理由
## 用途があいまい
単にコードを折りたたむだけの機能なので、コードのブロック単位を無視した使い方ができます。
コード規約で縛るのであればまだしも、無秩序に使われると可読性が逆に低下します。

例えばこんなコードは

```Huga.cs
public class Huga
{
    #region Member variables
    private string _initialValue;
    #endregion

    #region Public methods
    public bool SetInitialValue(string value)
    {
        #region Check input
        if (string.IsNullOrEmpty(_initialValue))
        {
            return false;
        }
        #endregion
        #region Set value
        _initialValue = value;
        #endregion
        return true;
    }
    #endregion
}
```
こんな風になります。ネストして使われるとわけがわからないよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212876/ad145434-e530-c34f-24e0-6a1b6b15140d.png)

## 保守が難しくなる

Windowsフォームのコードを例として出します。
下記のクラスにメンバを追加するとき、正しい位置に追加するには#region-#endregionのブロックをいちいち調べなければいけません。
労力に見合うほどのリターンが、果たしてあるのでしょうか？

```PiyoForm.cs
public partial class PiyoForm : Form
{
    #region Member variables
    private bool _isInitialized;
    #endregion

    #region Constructor
    public PiyoForm()
    {
        InitializeComponent();
    }

    #endregion

    #region Event handler
    private void PiyoForm_Load(object sender, EventArgs e)
    {
        // Something
    }

    private void Button1_Click(object sender, EventArgs e)
    {
        // Something
    }
    #endregion

    #region Private methods
    private void ProcessSomething()
    {
        // Something
    }
    #endregion
}
```


## リファクタの必要性を隠してしまう
&#35;regionがなければ読みづらいコードは、そもそもリファクタを必要としている可能性が高いです。
長大なメソッドをの可読性を上げるために#regionで分割することがよくありますが、そもそもメソッドを分割しておけば#regionを使う必要はなく、より可読性も向上します。

# 例外
## 長大なリテラルを隠すのに使う
多次元配列やヒアドキュメントのリテラルがコードの途中にあると、
膨大な行を使ったり、インデントを崩したりするので、読みやすさをかなり損ねてしまいます。
リテラルに用途を絞って&#35;regionを使うのは可読性の向上に有効と言えます。

```LongLongLiterals.cs
public class LongLongLiterals
{
    public void ProcessSomething()
    {
        var identityMatrix =
        #region Two dimensional array literal
            new int[,]
        {
            { 1, 0, 0, 0, 0, 0, 0, 0},
            { 0, 1, 0, 0, 0, 0, 0, 0},
            { 0, 0, 1, 0, 0, 0, 0, 0},
            { 0, 0, 0, 1, 0, 0, 0, 0},
            { 0, 0, 0, 0, 1, 0, 0, 0},
            { 0, 0, 0, 0, 0, 1, 0, 0},
            { 0, 0, 0, 0, 0, 0, 1, 0},
            { 0, 0, 0, 0, 0, 0, 0, 1}
        };
        #endregion
        var sql =
        #region Sql statement literal
            @"SELECT *
FROM dbo.Hoge
WHERE id = 1 and name = 'Jane Doe'";
        #endregion
    }
}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212876/1612fe80-c82c-f5ee-d0a6-496249172c0c.png)

# まとめ
便利機能として多用されることの多い&#35;regionの注意点について解説しました。
どうしても#regionを多用したコードを向き合わざるを得ない場合に、役立つアドオンを最後にご紹介しておきます。どちらのアドオンも、&#35;regionをデフォルトで展開状態にしてくれます。

- VS2017,2019
 - [#Regions Are Evil - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=PaulMelia.RegionsAreEvil001)
- ～VS2015
 - [I Hate #Regions - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=Shanewho.IHateRegions)