========================================================================
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_` カテゴリのドキュメントに記載する．
