dotnet/corefxリポジトリ内のC# Coding Styleの日本語訳です。
コード部分および脚注は自分が書き加えたものです。
C++ファイル(*.cpp, *.h)
- __clang-format (version 3.6+)__に準拠する。
- マージ前にsrc/Native/format-code.shを実行して、コードの自動整形をすること。
コードファイル以外(*.xmlなど)
- フォーマットの一貫性を優先する。
- 修正の場合は、既存のフォーマットに準拠する。
- 新規作成の場合は、すでに作成された同種ファイルのフォーマットに準拠する。
- 準拠する既存のファイルがない場合は、広く受け入れられたスタイルであればOK。
C#ファイル(*.cs)
基本的にVisual Studioの初期設定に準ずる。
ブラケット{ }
- Allman styleに準拠する。
- 単一ステートメントのブラケットなし表記は許容するが、「インデントが適切である」「他のステートメントでネストされていない」場合のみ。(参考issue#381)
-
using
ステートメントは例外で、他のusing
にネストされていてもブラケットを省略可能。
Braces
// OK
public void Foo(int x, string y)
{
// 単一ステートメントの場合は{ }がなくてもよい
if (x < 0) throw new ArgumentException();
// 2行に分ける場合も同様。ただしインデントは下げる
if (y == null)
throw new ArgumentNullException("Exception Message");
// ネストされている場合は{ }必須
if (x == 0)
{
if (y == "")
{
Console.WriteLine("String Empty");
}
Console.WriteLine("Int 0");
}
// 例外的に、usingはネストを深くしなくてよい
using (var sr = new StreamReader())
using (var sw = new StreamWriter())
{
// srとswのスコープはこのブロック内
}
}
// NG(K&R style)
public void Bar(int x, string y) {
// NGではないが、早期returnに{ }があるのは嫌われがち(issue#381)
if (x < 0) { throw new ArgumentException(); }
// NG(インデントを下げていない)
if (y == null)
throw new ArgumentNullException("Exception Message");
// これはFooクラスと異なるコードパスとなる。
// 以下のように解釈される。
// =============================
// if (x == 0)
// {
// if (y == "")
// {
// Console.WriteLine("String Empty");
// }
// }
// Console.WriteLine("Int 0");
// =============================
// 上記のような勘違いを起こさないように、{ }を必須としている。
if (x == 0)
if (y == "")
Console.WriteLine("String Empty");
Console.WriteLine("Int 0");
}
インデント
- 半角スペース4つ。(タブ文字は使わない)
フィールド
-
internal
、private
フィールドの場合は_camelCase
のように命名する。- インスタンスフィールドは
_
をつける -
static
フィールドはs_
をつける - スレッド内で
static
なフィールドにはt_
をつける
- インスタンスフィールドは
- 可能ならば
readonly
をつける -
static
とreadonly
が重複する場合は、static readonly
の語順にする。 -
public
フィールドは多用しない。 使用する場合はPascalCase
のように命名する。
Fields
using System.Threading;
public class Foo
{
private int _count;
private static readonly string s_foo;
[ThreadStatic]
private static string t_bar;
public string PublicField;
}
this参照
- 必要でない限りは、
this.
表記を使わない。
This
public class Foo
{
// フィールドの命名規約に違反していますが、例ということでご容赦を……。
private readonly int x;
private readonly int y;
public Foo(int x)
{
// thisを付けないと引数のxとみなされるため、必須
this.x = x;
// NG yでアクセス可能
this.y = 20;
}
}
アクセシビリティ
- 省略可能な場合であっても、
private
などのアクセシビリティは明示する。 - アクセシビリティは先頭に書く。
Visiblity
internal class Foo // OK
{
private string _text; // OK
}
public abstract class Bar // OK
{
}
class Foo // NG(明示的にinternalを書く)
{
string _text; // NG(明示的にprivateを書く)
}
abstract public class Bar // NG(public abstractの順)
{
}
名前空間
- 名前空間のインポート(
using
)は、ファイルの先頭かつ、namespace
ブロックの外で行う。 -
System.*
以外の名前空間は、アルファベット順にソートする。 -
System.*
のインポート句は、先頭に持ってくる。
Namespace
using System;
using System.Text;
using ACorp.Library;
using BCorp.Library;
using BCorp.Library.IO;
namespace ACorp.Product
{
}
空白行
- 空白行は1行まで。2行以上の空白行は認めない。
スペース
- 行末のスペースなど、不要な空白は削除する。
- IDEで明示的にスペースが見える設定にしておく。(Visual StudioではCtrl+E, S)
// NG 見た目ではわかり辛いが、下の行末にスペースが3個ある
if (index == 0)
{
}
既存コード
- 既存のコードファイルに、この規約に沿わないものがあった場合は、そのファイル内では既存の表記に従う。1
var
- 右辺から型が明らかな場合のみ使用する。
Var
var stream = new FileStream(); // OK
var stream = OpenStandardInput(); // NG 戻り値の型を知らなければならない
組み込み型
- BCLの型名(
Int32
など)ではなく、キーワード(int
)を使用する。(参考issue#391) -
int.Parse
など、メソッドを呼び出す際も同様。
定数(const
)
- ローカル定数とフィールド定数は、
PascalCase
で命名する。- ネイティブコード呼び出し等で定数名と値を合わせる必要がある場合には、この限りではない。
nameof
- 可能な限り、
"Foo"
ではなくnameof(Foo)
演算子を利用する。
NameOf
public void Method(int index)
{
// nameof演算子はコンパイル時に定数に変換される。
// つまり、下記if文は同じ意味。
// ただしnameof演算子を利用することで、IDE上での参照が追えるようになる。
// (例えば引数indexをリネームした場合、前者は変更が追えるが後者は追えない)
if (x < 0) throw new ArgumentException(nameof(index));
if (x < 0) throw new ArgumentException("index");
}
フィールド宣言
- フィールドは、型宣言の先頭に定義する。
非ASCII文字
- 非ASCII文字は、Unicodeエスケープリテラル(
\uXXXX
)を用いて表記する。- 非ASCII文字に非対応のエディタで問題が起きないようにするため。
gotoラベル
-
goto
用のラベルを書く際には、インデントを1段階上げる。
public void Method(int x)
{
if (x < 0) goto Negative;
DoSomething(x);
Negative: // インデントを1段階上げる
DoFinally();
}
ツール類
EditorConfig
- corefxリポジトリのルートにある.editorconfigファイルで、上記規約をルール化している。
- EditorConfigに対応しているエディタならば、上記の規約に従うよう自動整形される。2
.NET Codeformatter Tool
- 実行時に、自動で上記の規約に沿うようファイルを整形するツール。
メモ
-
.editorconfig
の作成は、Visual Studio 2017以降で(.NET拡張部分も含め)グラフィカルに行える。 - .NET Codeformatter Toolはcorefx専用感が強いので、自プロジェクトで使う場合はdotnet-formatを利用する
-
.editorconfig
に基づいてコードを整形してくれるツール