========================================================================
C# コーディング規則 (C# Coding Style Guide)
========================================================================
1. 基本方針 (Basic Policy)
------------------------------------------------------------------------
Microsoft の C# コーディング規則および .NET ランタイム コーディングガイド
ラインを基本とし,チーム内での一貫性を最優先とする.
本規則に明記されていない事項は Microsoft 公式ガイドラインに従う.
※ 書式・記述スタイルの基準は `GUIDE_01_ドキュメント作成ガイド.txt` を参照する.
2. フォーマット (Formatting)
------------------------------------------------------------------------
2-1. インデント
・半角スペース4つを使用する.タブ文字は使用しない.
・継続行は,開き括弧に揃えるか,ハンギングインデント(スペース4つ追加)とする.
・例:
// 開き括弧に揃える
var result = SomeMethod(argOne, argTwo,
argThree, argFour);
// ハンギングインデント
var result = SomeMethod(
argOne, argTwo,
argThree, argFour);
2-2. 波括弧 (Braces)
・開き波括弧「{」は,宣言と同じ行に記述する(K&R スタイル).
・例:
namespace TIASshot {
internal class MotorController {
public void Start() {
if (IsRunning) {
...
}
}
}
}
・単文の `if` / `for` 等でも,必ず波括弧を付ける.
- NG: `if (isActive) return;`
- OK: `if (isActive) { return; }`
2-3. 1行の最大文字数
・120文字を目安とする.超える場合は適切な位置で改行する.
2-4. 空行
・クラス定義の間: 2行空ける.
・メソッド定義の間: 1行空ける.
・メソッド内の論理的なまとまりの区切り: 1行空ける(使いすぎに注意).
2-5. 文字コード
・UTF-8(BOM なし)を使用する.
3. 命名規則 (Naming Conventions)
------------------------------------------------------------------------
3-1. 一覧
■ クラス・構造体・列挙型・デリゲート
・スタイル: PascalCase
・例: `CameraBase`,`MotorController`,`DeviceStatus`
■ インターフェース
・スタイル: 「I」プレフィックス + PascalCase
・例: `ICamera`,`IDeviceControl`
■ メソッド・イベント・プロパティ
・スタイル: PascalCase
・例: `Connect()`,`GetDataName()`,`IsCalibrating`
■ ローカル変数・引数
・スタイル: camelCase
・例: `cameraList`,`saveFolder`,`numImages`
■ プライベートフィールド
・スタイル: アンダースコア + camelCase
・例: `_camera`,`_isLightOn`,`_calibrating`
■ 定数・static readonly フィールド(公開)
・スタイル: PascalCase
・例: `MaxSpeed`,`DefaultPort`,`AppName`
※ 既存コードの `UPPER_SNAKE_CASE`(例: `APP_NAME`)は互換性のため許容するが,
新規定義は `PascalCase` に統一する.
■ 非同期メソッド
・スタイル: PascalCase + `Async` サフィックス
・例: `ConnectAsync()`,`SaveImagesAsync()`,`LoadConfigAsync()`
■ 列挙型メンバー
・スタイル: PascalCase
・例: `DeviceStatus.Connected`,`CaptureMode.Single`
3-2. 命名の原則
・意味のある名前を付け,略語は最小限にする.
- NG: `d`,`tmp`,`val`
- OK: `distance`,`temperature`,`motorValue`
・ループカウンタ等,スコープが極めて狭い場合のみ `i`,`j`,`x`,`y` を許容する.
・bool 型のプロパティ・変数は `Is`,`Has`,`Can` 等の接頭辞を付ける.
- 例: `IsConnected`,`HasObstacle`,`CanCapture`
4. using ディレクティブの規則 (Using Directives)
------------------------------------------------------------------------
4-1. 順序
以下の順序で記述し,グループ間に1行空ける.
1. System 名前空間(`System`,`System.Collections.Generic` 等)
2. サードパーティライブラリ(`OpenCvSharp`,`TIS.Imaging` 等)
3. プロジェクト内名前空間
・例:
using System;
using System.Collections.Generic;
using System.IO;
using OpenCvSharp;
using TIASshot.Camera;
4-2. スタイル
・不要な `using` は削除する.
・`using static` は,同一クラスのメンバーを多用する場合のみ許容する.
5. 型の使用規則 (Type Usage)
------------------------------------------------------------------------
5-1. var の使用
・右辺に型名が明示されている場合は `var` を使用する.
- OK: `var list = new List<string>();`
- OK: `var controller = new MotorController();`
・右辺から型が読み取れない場合は明示的な型を使用する.
- NG: `var result = GetResult();`(戻り値の型が不明確)
- OK: `XmlNode result = doc.SelectSingleNode("//Config");`
5-2. null 許容参照型 (Nullable Reference Types)
・`null` との比較は `is null` / `is not null` を使用する.
- NG: `if (value == null)`
- OK: `if (value is null)`
・null 合体演算子(`??`,`??=`)や null 条件演算子(`?.`,`?[]`)を積極的に活用する.
6. コーディングルール (Coding Rules)
------------------------------------------------------------------------
6-1. 文字列
・文字列の組み立てには文字列補間(`$"..."`)を使用する.
- NG: `"Speed: " + speed.ToString()`
- OK: `$"Speed: {speed}"`
・定数文字列は `const string` または `static readonly string` で定義する.
6-2. 例外処理
・裸の `catch (Exception)` は極力避け,具体的な例外クラスを指定する.
- NG: `catch (Exception) { }`
- OK: `catch (ArgumentException ex) { ... }`
・例外を握りつぶす場合(空の catch 節)は,必ず理由をコメントで明記する.
6-3. リソース管理
・`IDisposable` を実装するオブジェクトは `using` 文で管理する.
・例:
using (var reader = new StreamReader(csvFile)) {
while (!reader.EndOfStream) {
...
}
}
6-4. マジックナンバーの禁止
・意味のある数値や文字列は定数として定義する.
- NG: `Thread.Sleep(500);`
- OK:
const int SensorIntervalMs = 500;
Thread.Sleep(SensorIntervalMs);
6-5. readonly の使用
・コンストラクタ以降に値が変わらないフィールドは `readonly` を付ける.
- NG: `private float _updateRate;`(コンストラクタで1度だけ代入する場合)
- OK: `private readonly float _updateRate;`
・`static readonly` はクラス定数(`const` にできない参照型など)に使用する.
6-6. プロパティ vs 公開フィールド
・`public` フィールドは原則定義しない.外部に公開する値はプロパティを使用する.
- NG: `public string DeviceName;`
- OK: `public string DeviceName { get; protected set; }`
・外部から読み取りのみ許可する場合は `get` のみ,または `{ get; private set; }` とする.
6-7. アクセス修飾子
・アクセス修飾子は必ず明示する(省略しない).
- NG: `class Config { ... }`
- OK: `internal static class Config { ... }`
6-8. UI スレッド
・ワーカースレッドから UI 操作を行う場合は `InvokeRequired` を確認してから
`Invoke` / `BeginInvoke` を使用する.
・例:
public void ShowMessage(string msg) {
if (InvokeRequired) {
Invoke((MethodInvoker)delegate { ShowMessage(msg); });
return;
}
txtMessage.Text = msg;
}
7. ファイル構成 (File Structure)
------------------------------------------------------------------------
1つの C# ファイル内は,以下の順序で記述する.
1. using ディレクティブ
2. namespace 宣言
3. クラス定義(フィールド → プロパティ → コンストラクタ → メソッド)
・例:
using System;
using System.IO;
namespace TIASshot {
internal class MotorController {
// フィールド
private bool _isRunning = false;
// プロパティ
public bool IsRunning => _isRunning;
// コンストラクタ
public MotorController() {
...
}
// メソッド
public void Start() {
...
}
}
}
8. ツール設定 (Tooling)
------------------------------------------------------------------------
コードの品質を自動で維持するため,以下のツールの導入を推奨する.
■ フォーマッター
・`.editorconfig` に本規則の設定を記述し,チームで共有する(IDE 共通).
・Visual Studio: Ctrl+K, Ctrl+D でフォーマットを実行する.
・VSCode: C# Dev Kit 拡張機能を導入し,Shift+Alt+F でフォーマットを実行する.
- 保存時自動フォーマット(`editor.formatOnSave: true`)の設定を推奨する.
■ リンター
・Roslyn Analyzers を使用する(Visual Studio・VSCode 共通で動作する).
- `Microsoft.CodeAnalysis.NetAnalyzers` パッケージの導入を推奨する.
■ 型チェック
・Visual Studio・VSCode いずれの場合も,ビルドエラー・警告を全て解消してからコミットする.
・dotnet CLI: `dotnet build` でエラーがないことを確認する.
※ ツールの具体的な設定や導入手順は `ENV_` カテゴリのドキュメントに記載する.