C#のコードフォーマット設定を共有する方法

  • 20
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

背景

UnityでC#を使って複数人で開発していてコードフォーマットが
(コーディング規約を決めてはいたものの)人によってバラバラという状況に。。。
そこでコマンドラインからドバーッとコード整形できるツールを探していたところ
Artistic Styleというものが中々よさげだったので紹介したいと思います。

Artistic Styleとは

コマンドラインから実行できるコードフォーマッター。
macでのinstall方法はこちら => http://astyle.sourceforge.net/install.html#_Mac_OS_X_Version

使い方

astyle path/to/target_file
astyle --style=allman path/to/target_file # allmanスタイルで整形
astyle -bps4 # -b -p -s4 を指定したのと同じ
astyle --options=path/to/option_file # 任意のオプションファイル読み込み 

オプションの指定方法は引数を渡す方法と
オプションファイルを設定する方法があります。
オプションファイルは~/.asytlercに書いておくか、
--options=path/to/option_fileで任意の場所のファイルを指定できます。

設定例

microsoftのC#のコーディング規約( https://msdn.microsoft.com/ja-jp/library/ff926074.aspx )
に近くなるように色々試して設定してみた例を書いときます

# c#のファイルとして認識する
mode=cs
# allmanスタイルにする
style=allman
# インデントにタブを使う
indent=tab=4
# 継続行のインデントにもタブを使う(但し偶数個のタブでないときはwhite spaceで埋められる)
indent=force-tab=4
# namespace文の中をインデントする
indent-namespaces
# switch文の中をインデントする
indent-switches
# case文の中をインデントする
indent-cases
# 1行ブロックを許可する
keep-one-line-blocks
# 1行文を許可する
keep-one-line-statements
# プリプロセッサをソースコード内のインデントと合わせる
indent-preproc-cond
# if, while, switchの後にpaddingを入れる
pad-header
# 演算子の前後にpaddingを入れる
pad-oper
# originalファイルを生成しない
suffix=none
# if, for, while文の前後に空行を入れる
break-blocks
# コメントもインデントする
indent-col1-comments

自分のプロジェクトに応じて、色々と設定を変更してみると良いと思います!

ビフォーアフター

適当につくったファイルに対してasytleを適用してみます。

ビフォー

using System;

namespace test {
class MainClass {
    public static void Main(string[] args) {
        int localVariable1=1;

        bool isEnabled = false;
        if (isEnabled) {
#if FALSE
//dosomething
            #else
//dosomething
            #endif
            Console.WriteLine("is enabled");
        } else {
            Console.WriteLine("is not enabled");
        }
            if (isEnabled) { Console.WriteLine("one line if statement.");}
        for(int i=0; i<10; i++)
    {
                Console.WriteLine(i.ToString());
            }
            switch(localVariable1)
            {
                case 1:
                    int localVariable2 = 2;
                    localVariable2 += localVariable1;
                Console.WriteLine("localVariable2 = " + localVariable2.ToString());
                    break;
                default:
                break;
            }
}
}
}

アフター

using System;

namespace test
{ // <= allmanスタイルの字下げスタイルが適用されてる
    class MainClass // <= indent-namespacesでnamespace内がインデントされてる
    {
        public static void Main(string[] args)
        {
            int localVariable1 = 1; // <= pad-operで = の前後に空白が入ってる

            bool isEnabled = false;

            if (isEnabled) // <= break-blocksでif文の前後に空白行が入ってる
            {
                #if FALSE // <= indent-preproc-condでインデントされてる
                //dosomething // <= indent-col1-commentsでインデントされてる
                #else
                //dosomething
                #endif
                Console.WriteLine("is enabled");
            }
            else
            {
                Console.WriteLine("is not enabled");
            }

            if (isEnabled) { Console.WriteLine("one line if statement.");} // <= keep-one-line-statementsで1行if文はそのまま

            for (int i = 0; i < 10; i++) // <= pad-headerでforの後に空白が入ってる
            {
                Console.WriteLine(i.ToString());
            }

            switch (localVariable1)
            {
                case 1: // <= indent-switchesでswitch文内がインデントされてる
                    int localVariable2 = 2; // <= indent-casesでcase文内がインデントされてる
                    localVariable2 += localVariable1;
                    Console.WriteLine("localVariable2 = " + localVariable2.ToString());
                    break;

                default:
                    break;
            }
        }
    }
}

大分見やすくなりました!
あとはこれをgitのpre-commitフックとかに仕掛けとけばコードフォーマットが綺麗に保たれるはず!