目次
C#命名規則の基本
命名規則とは?
命名規則とは、クラス名や変数名などの名前の付け方をチームで統一するためのルールです。
英単語の選び方(動詞・名詞)、大文字小文字(PascalCase / camelCase)、略語の扱いをあらかじめ決めておくことで、コードが読みやすくなり、検索しやすくなり、ミスが減ります。
初心者ほど「とりあえず動けばOK」になりがちですが、未来の自分、あるいは他人が読んだときの負担を小さくする“投資”だと考えてください。
命名規則を決めることによる効果
- 可読性UP
大文字小文字や単語の並べ方が一定だと、パターン認識が働き、意味を瞬時に把握できます。
C#では「型やプロパティはPascalCase」「ローカル変数はcamelCase」にするのが一般的で、このように役割ごとにルールを決めることで、名前を見るだけで役割が推測できるようになります。 - 検索性UP
エディタでFindやGo to Symbolを使うとき、命名規則が一貫していれば、目的の定義にすぐ辿り着けます。
たとえば「取得する動作はGet」「作成するのはCreate」「試行はTry」といった動詞の定番を決めておくと、「何で検索すればよいか」が明確になります。 - バグ減少
メソッド名がCalculateTotalなのにキャッシュから返すだけだと、期待と実装の不一致が起きます。
命名を正すことは、仕様の誤解を早期にあぶり出す効果があります。 - レビュー効率UP
「idとIdどっち?」のような表記ゆれの指摘をなくし、レビューを本質的な設計・アルゴリズムの議論に集中できます。 - ツールとの相性UP
ルールが定まっていれば.editorconfigやアナライザで自動チェックできます。
人間が全部を見張る必要がなくなります。
命名規則の最小構成
以下のルールを守るだけで読みやすさは大きく改善します。
| 対象 | 命名規則 | 記述例 |
|---|---|---|
| 型名 メソッド名 プロパティ名 | PascalCase (各単語の先頭が大文字) | UserService GetUserById CreatedAt |
| ローカル変数 引数 | camelCase (先頭が小文字+単語境界で大文字) | userId createdAt |
| bool型変数 | 肯定形の質問系/状態系 | isActive hasItems canExecute |
| メソッド名 | 動詞で始める | Get Set Find Create Update Delete Calculate Validate TryParse |
| コレクション名 | 複数形にする | users orderItems lines |
| クラス名 | 名詞/役割名にする ※抽象語は避ける(Manager/Helper/Utilなど) | User OrderRepository EmailSender |
| 定数 | PascalCase+名詞 | DefaultPageSize MaxRetries |
| 非同期メソッド | 末尾にAsyncを付ける | GetUserAsync SaveChangesAsync |
名前の長さと具体性のバランス
- 短すぎて意味不明なものはNG(例:d, tmp, man)
- 長すぎるのもNG(例:GetAllUsersFromDatabaseAndSortByCreatedAtAscending)
- 原則は「具体性>省略」だが、局所スコープのループ変数などは短くてOK(例:i, x, line)
- だいたい3単語ぐらいに収まるのが目安
- どうしても長くなる場合は設計を見直すサイン
初心者あるある
- 日本語直訳やローマ字を使ってしまう。(例:TourokuUser)
⇒英語に統一しましょう。(RegisterUser) - 略語を乱用してしまう。(usr, cfg, svc)
⇒なるべくフルスペルで書きましょう。読みやすさ優先です。 - bool型変数名を否定形にしてしまう。
⇒isNotEnabledは読みにくい。否定形の表現は肯定形+条件反転にしましょう。(例:if( !isEnabled ){})
PascalCase と camelCase:C#での使い分け早見表
「どこを大文字にするか」を迷わなくするために、用途ごとの“型”を決めましょう。
C#/.NET では役割によって書式が違うので、形だけで“それが何者か”が分かるようになります。
| 対象 | 命名規則 | 記述例 |
|---|---|---|
| クラス 構造体 レコード | PascalCase (名詞で役割を表す) | UserServiceOrderEmailMessage |
| インターフェイス | PascalCase + I接頭辞(実装と区別しやすい) | IUserRepositoryILogger |
| 列挙型(enum) 列挙子 | PascalCase | OrderStatus |
| 名前空間(namespace) | PascalCase (セグメントごとにPascalCase) | MyCompany.Shop.Api |
| メソッド | PascalCase (動詞で開始/非同期は末尾 Async) | GetUserByIdSendEmail |
| プロパティ イベント | PascalCase (名詞/形容詞で状態を表す) | UserIdCreatedAtCompleted |
定数(const) | PascalCase (値は不変。大文字スネークは使わない) | DefaultPageSizeMaxRetryCount |
| フィールド(private) | _camelCase (先頭アンダースコア + camelCase が定番) | _db_cache_httpClient |
| static フィールド(private) | _camelCase(または s_系)(チームで統一。初心者は _でOK) | _instance |
| 引数 / ローカル変数 | camelCase (短く明確に) | userIdcountisActive |
| ラムダ引数(LINQ) | camelCase(慣用名可) (短くてOK、 item等も多い) | xuserline |
| ジェネリック型パラメータ | Tで始める | TItemTKeyTValue |
ルールと理由をセットで理解すると覚えやすい
- 公開される名前はPascalCase
⇒クラス・メソッド・プロパティなどはAPIの顔。視認性が高いPascalCaseで、英単語の境界が読み取れる書き方にします。GetUserByIdとgetuserbyidを見比べると、可読性の差は明らかです。 - 内部で使う名前(変数・引数)はcamelCase
⇒コードの流れの中で読む対象。文中に溶け込みやすく、先頭小文字→後続単語の頭を大文字で区切ることで、読みやすさとコンパクトさを両立します。userId,createdAt,isEnabledなど。 - private フィールドは
_camelCase
⇒this.と見分けやすく、メソッドの引数・ローカル変数とも衝突しにくいのが利点です。_db,_cache,_loggerのように“裏方の部品”感が出ます。 - 定数(
const)はPascalCase
⇒C#ではMAX_VALUEのような完全大文字スネークケースは原則使いません。メンバーと同じくPascalCaseで、人が読む名詞にします(DefaultTimeoutなど)。static readonlyも不変概念のときはPascalCaseに寄せると分かりやすい。 - boolは Is/Has/Can で始める
⇒IsActive,HasItems,CanExecuteのように質問に答える形にすると、条件式が自然文のように読めます。if (isActive && hasItems) { ... }は直感的です。 - 非同期は
Asyncサフィックス
⇒GetUserAsync,SaveChangesAsyncのように末尾固定で付けます。呼び出し時にawaitを忘れにくくなり、同期版と視覚的に区別できます。
よく使う役割別の命名ガイド
「どの動詞を先頭に置くか」「boolはどんな接頭辞にするか」を最初に決めておくと、命名に迷いません。
C#/.NETでよく使う命名を役割別にリスト化し、選び方の基準と記述例で命名規則を覚えていきましょう。
| 目的 | 推奨動詞 | 使い分けの基準 | 記述例 |
|---|---|---|---|
| 取得 (存在が前提) | Get | 存在する前提で取り出す。 なければ例外。 | GetUserById(int userId) |
| 検索 (ないかも) | Find | 見つからない可能性がある。 見つからなければnullを返す。 | FindUser(string email) |
| 安全な取得 | TryGet | 例外を出さず、bool で成否+outを返す。 | TryGetUser(int id, out User user) |
| 作成 (インスタンス生成) | Create | 新しいものを作る。 (戻り値が新インスタンス) | CreateOrder(CreateOrderRequest req) |
| 追加 (集合に入れる) | Add | 既存のコレクションやDBにデータを加える。 | AddItem(OrderItem item) |
| 更新 (既存の変更) | Update | 既存オブジェクト/レコードの内容を変更する。 | UpdateEmail(int userId, string email) |
| 削除 (永続データ) | Delete | DB/ファイルなどを削除する。 | DeleteUser(int userId) |
| 取り除く (コレクション) | Remove | コレクションやキャッシュからデータを取り除く。 | RemoveItem(Guid id) |
| すべて消す | Clear | コレクションの内容をすべて消す。 | ClearCache() |
| 読み込み | Load Read | ファイル/ストレージからデータを読み取る。 | LoadSettings() |
| 保存 | Save Write | 設定/データを保存する。 | SaveSettings(Settings s) |
| 変換 | Convert ToXxx FromXxx | 型変換・表現変換。 | ToDto(User u)FromJson(string json) |
| 解析 (文字列⇒型) | Parse TryParse | 文字列⇒型。 失敗時の方針で使い分け。 | DateTime.TryParse(...) |
| 計算 | Calculate Compute | 関数的な計算。 | CalculateTotal() |
| 検証 | Validate | 値や状態が条件を満たすか確認する。 (違反⇒結果 or 例外) | ValidatePassword(string value) |
| 保障 (なければ用意) | Ensure | 条件を満たすようにする。 (無ければ作る) | EnsureDirectory(string path) |
| 開始 / 停止 | Start Stop | プロセス・監視・タイマーなどを開始/停止する。 | StartTimer()StopTimer() |
| 有効 / 無効化 | Enable Disable | 機能トグル。 | EnableFeature(string name) |
| 接続 / 切断 | Connect Disconnect | ネットワーク・DBなどの接続/切断。 | ConnectAsync()Disconnect() |
最後に
命名は「作法」ではなく「仕様の圧縮」です。
良い命名は、頭の中にある変換作業を最小化し、コードだけで仕様が語れる状態を作ります。
作法として丸暗記するのではなく、「名前=契約」という視点で命名してコーディングするように心がけましょう。
命名規則を守ることができれば、プロジェクトは速く・安全に拡張できます。
コメント