Newer
Older
TIASshot / docs / 01_GUIDE / GUIDE_04_コーディング規則.txt
========================================================================
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_` カテゴリのドキュメントに記載する.