C#の命名規則・コーディングルール完全ガイド|初心者が迷う書き方を実例で解説

はじめに

C#を書き始めたばかりの人が最初につまずきやすいのが、「動くコード」と「読みやすいコード」の違いです。文法としては正しくても、変数名が分かりにくい、インデントがバラバラ、メソッドが長すぎる、といったコードは後から読むのが大変になります。

C#には、コンパイラがチェックする文法ルールだけでなく、開発者同士が読みやすさを保つための命名規則やコーディングルールがあります。これらは必ずしもすべてが強制されるわけではありませんが、守ることで保守しやすく、バグを見つけやすいコードになります。

この記事では、C#の命名規則、書式ルール、設計ルール、よくある悪い例、自動整形の方法まで、初心者が迷いやすいポイントを実例付きで解説します。

1. C#のルールとは?初心者が最初に知るべき全体像

C#のルールと聞くと、まず「文法」を思い浮かべる人が多いかもしれません。しかし、実際の開発では文法だけでなく、名前の付け方、インデント、コメント、例外処理、クラス設計など、さまざまなルールを意識する必要があります。

C#のルールは、大きく分けると「コードを動かすためのルール」と「コードを読みやすく保つためのルール」に分けられます。

1-1. C#の「文法ルール」と「コーディングルール」の違い

文法ルールとは、C#として正しくプログラムを動かすために必要な決まりです。たとえば、セミコロンを付ける、波かっこでブロックを囲む、型に合った値を代入する、などが該当します。

C#
int age = 20;
Console.WriteLine(age);

一方、コーディングルールとは、コードを読みやすく、保守しやすくするための決まりです。たとえば、クラス名はPascalCaseにする、ローカル変数はcamelCaseにする、メソッドは動詞から始める、などがあります。

C#
public class UserService
{
public User GetUserById(int userId)
{
// 処理
}
}

文法ルールに違反するとコンパイルエラーになりますが、コーディングルールに違反してもコード自体は動くことがあります。しかし、チーム開発や長期運用では、コーディングルールを守ることが非常に重要です。

1-2. コーディングルールを守るメリット

C#のコーディングルールを守る最大のメリットは、コードの読みやすさが上がることです。名前の付け方や書式が統一されていると、他人のコードでも意図を理解しやすくなります。

また、ルールが統一されているとレビューの負担も減ります。「この変数名は大文字にするべきか」「privateフィールドにアンダースコアを付けるべきか」といった細かい議論を減らし、本質的な設計やロジックに集中できます。

さらに、ルールに沿ったコードはバグの発見もしやすくなります。たとえば、bool型の変数名がisActivehasPermissionのようになっていれば、条件式を読んだときに意味がすぐ分かります。

1-3. 命名規則・書式・設計ルールの主な分類

C#のコーディングルールは、主に次のように分類できます。

命名規則は、クラス名、メソッド名、変数名、プロパティ名、インターフェース名などの名前の付け方に関するルールです。C#ではPascalCase、camelCase、_camelCaseを使い分けるのが一般的です。

書式ルールは、インデント、スペース、改行、波かっこの位置、usingの並び順など、コードの見た目に関するルールです。

設計ルールは、メソッドを短くする、クラスの責務を分ける、重複コードを減らす、マジックナンバーを避ける、といった保守性に関するルールです。

どれも「読みやすいC#コード」を書くために欠かせない要素です。

1-4. 迷ったらMicrosoft公式のC#コーディング規則を基準にする

C#の命名規則やコーディングルールに迷った場合は、Microsoftの公式ガイドラインを基準にするのがおすすめです。C#はMicrosoftが開発している言語であり、公式ドキュメントや.NETのコード例では、標準的な書き方が多く使われています。

ただし、すべてのプロジェクトで完全に同じルールを使う必要はありません。会社やチームによって、privateフィールドにアンダースコアを付けるかどうか、varをどの程度使うか、1行の長さを何文字までにするかなどは異なります。

大切なのは、プロジェクト内で一貫したルールを決め、それを継続して守ることです。

2. C#の命名規則の基本

C#の命名規則は、コードの読みやすさに直結します。名前を見ただけで、それがクラスなのか、メソッドなのか、変数なのかが分かると、コード全体を理解しやすくなります。

ここでは、C#でよく使われる基本的な命名ルールを整理します。

2-1. PascalCase・camelCase・_camelCaseの違い

C#でよく使われる命名形式は、PascalCase、camelCase、_camelCaseの3つです。

PascalCaseは、各単語の先頭を大文字にする書き方です。

C#
UserService
GetUserName
OrderItem

クラス名、メソッド名、プロパティ名、publicメンバーなどによく使います。

camelCaseは、最初の単語を小文字にし、2語目以降の先頭を大文字にする書き方です。

C#
userName
orderCount
totalPrice

ローカル変数やメソッドの引数によく使います。

_camelCaseは、camelCaseの先頭にアンダースコアを付ける書き方です。

C#
_userName
_orderCount
_totalPrice

privateフィールドに使われることが多い形式です。

2-2. クラス名の命名規則

C#のクラス名はPascalCaseで書くのが基本です。クラスは「もの」や「役割」を表すため、名詞または名詞句にします。

良い例は次のとおりです。

C#
public class User
{
}

public class UserService
{
}

public class OrderRepository
{
}

悪い例は次のような名前です。

C#
public class user
{
}

public class doUser
{
}

public class U
{
}

クラス名は、そのクラスが何を表しているのかを明確にすることが重要です。DataManagerのような曖昧な名前は便利に見えますが、責務が広がりやすいため注意しましょう。

2-3. メソッド名の命名規則

メソッド名はPascalCaseで書きます。メソッドは処理や動作を表すため、動詞または動詞句にするのが基本です。

C#
public void SaveUser(User user)
{
}

public User GetUserById(int userId)
{
}

public bool ValidateEmail(string email)
{
}

メソッド名は「何をするのか」が分かる名前にします。

悪い例は次のとおりです。

C#
public void User()
{
}

public void Do()
{
}

public void Process()
{
}

ProcessExecuteのような名前は抽象的すぎる場合があります。何を処理するのか、何を実行するのかが分かるようにしましょう。

2-4. 変数名・ローカル変数名の命名規則

ローカル変数名はcamelCaseで書きます。変数名は、値の意味が分かる名前にすることが大切です。

C#
int userCount = 10;
string userName = "Taro";
decimal totalPrice = 1500m;

悪い例は次のような名前です。

C#
int x = 10;
string str = "Taro";
decimal tp = 1500m;

一時的なループ変数としてijを使うことはありますが、基本的には意味が伝わる名前を付けましょう。

2-5. 引数・パラメーター名の命名規則

メソッドの引数名もcamelCaseで書きます。呼び出し側やメソッド内部で意味が分かるように、具体的な名前を付けます。

C#
public void UpdateUserName(int userId, string newName)
{
}

悪い例は次のとおりです。

C#
public void UpdateUserName(int id, string s)
{
}

idだけでも意味が分かる場面はありますが、複数のIDが登場する場合はuserIdorderIdのように対象を明確にしたほうが安全です。

2-6. プロパティ名の命名規則

プロパティ名はPascalCaseで書きます。プロパティは外部から参照されることが多いため、分かりやすい名前にする必要があります。

C#
public string UserName { get; set; }

public int Age { get; set; }

public bool IsActive { get; set; }

bool型のプロパティは、IsHasCanなどを使うと意味が伝わりやすくなります。

C#
public bool IsDeleted { get; set; }

public bool HasPermission { get; set; }

public bool CanEdit { get; set; }

2-7. フィールド名の命名規則

privateフィールドは、_camelCaseで書くスタイルがよく使われます。

C#
private readonly UserRepository _userRepository;
private int _retryCount;

一方で、チームによってはアンダースコアを使わずcamelCaseにする場合もあります。

C#
private readonly UserRepository userRepository;

どちらが絶対に正しいというより、プロジェクト内で統一することが重要です。特にコンストラクターの引数とフィールドを区別したい場合は、アンダースコア付きのprivateフィールドが読みやすいです。

C#
public class UserService
{
private readonly UserRepository _userRepository;

public UserService(UserRepository userRepository)
{
_userRepository = userRepository;
}
}

2-8. 定数名の命名規則

C#の定数はPascalCaseで書くのが一般的です。CやJavaのようにすべて大文字のスネークケースにするスタイルは、C#では標準的ではありません。

C#
public const int MaxRetryCount = 3;
public const string DefaultUserName = "Guest";

悪い例は次のとおりです。

C#
public const int MAX_RETRY_COUNT = 3;

ただし、既存プロジェクトで大文字スネークケースが採用されている場合は、そのルールに合わせることもあります。新規のC#プロジェクトではPascalCaseを基準にするとよいでしょう。

2-9. インターフェース名の命名規則

C#のインターフェース名は、先頭にIを付けてPascalCaseで書くのが一般的です。

C#
public interface IUserRepository
{
User FindById(int userId);
}

public interface ILogger
{
void Log(string message);
}

Iを付けることで、クラスではなくインターフェースであることがすぐに分かります。これはC#で広く使われている命名規則です。

2-10. enum・namespace・ファイル名の命名規則

enum名はPascalCaseで書きます。enumの値もPascalCaseにします。

C#
public enum OrderStatus
{
Pending,
Paid,
Shipped,
Canceled
}

namespaceもPascalCaseを使い、会社名やプロダクト名、機能名を階層で表すことが多いです。

C#
namespace MyApp.Services.Users
{
}

ファイル名は、基本的にクラス名と一致させます。

C#
UserService.cs
OrderRepository.cs
PaymentController.cs

1ファイルに1つの主要なクラスを置くと、目的のコードを探しやすくなります。

3. C#で避けたい命名ルール違反と悪い例

命名規則を守っているつもりでも、初心者のうちは分かりにくい名前を付けてしまいがちです。ここでは、C#で避けたい命名の悪い例を紹介します。

3-1. 意味が伝わらない変数名を避ける

変数名は、値の意味が分かる名前にします。

悪い例です。

C#
int d = 30;
string n = "Taro";

これでは、dnが何を表しているのか分かりません。

良い例です。

C#
int daysUntilExpiration = 30;
string userName = "Taro";

多少長くなっても、意味が明確な名前のほうが読みやすくなります。

3-2. 省略しすぎた名前を避ける

省略しすぎた名前も避けましょう。

C#
int usrCnt = 10;
decimal ttlPrc = 1500m;

書いた本人は分かっていても、他の人には伝わりにくい名前です。

C#
int userCount = 10;
decimal totalPrice = 1500m;

一般的に広く使われる省略形でない限り、単語は省略しないほうが安全です。

3-3. ハンガリアン記法を避ける

ハンガリアン記法とは、変数名に型を表す接頭辞を付ける書き方です。

C#
string strName;
int intCount;
bool bIsActive;

C#では型情報をIDEが表示してくれるため、変数名に型を含める必要はほとんどありません。型ではなく意味を表す名前にしましょう。

C#
string userName;
int userCount;
bool isActive;

3-4. 大文字・小文字の使い分けミスを避ける

C#では大文字と小文字が区別されます。そのため、命名規則が崩れると読みにくくなります。

悪い例です。

C#
public class userservice
{
public void getuser()
{
}
}

良い例です。

C#
public class UserService
{
public void GetUser()
{
}
}

クラス名とメソッド名はPascalCase、ローカル変数と引数はcamelCase、と覚えておくと迷いにくくなります。

3-5. 日本語・ローマ字・英語が混在する命名を避ける

C#では日本語の識別子も使えますが、実務では英語で命名することが一般的です。

避けたい例です。

C#
string namae;
int userNenrei;
bool is有効;

ローマ字、日本語、英語が混在すると読みづらくなります。

良い例です。

C#
string userName;
int userAge;
bool isActive;

チーム内で日本語コメントを使うことはありますが、クラス名や変数名は英語で統一するのがおすすめです。

3-6. bool型は状態が分かる名前にする

bool型はtrueまたはfalseを表すため、条件式に入れたときに自然に読める名前にします。

悪い例です。

C#
bool delete;
bool permission;
bool active;

良い例です。

C#
bool isDeleted;
bool hasPermission;
bool isActive;

条件式にすると違いが分かりやすくなります。

C#
if (isActive)
{
// 有効な場合の処理
}

IsHasCanShouldなどを使うと、bool型であることが伝わりやすくなります。

3-7. コレクションは複数形で分かりやすくする

Listや配列など、複数の要素を持つ変数は複数形にします。

C#
List<User> users = new();
string[] fileNames = Array.Empty<string>();

悪い例です。

C#
List<User> user = new();
string[] fileName = Array.Empty<string>();

単数形だと、1件のデータなのか複数件のデータなのか分かりにくくなります。コレクションはusersordersproductsのように複数形にしましょう。

4. C#のコーディングルール基本編

命名規則の次に重要なのが、コードの見た目を整えるコーディングルールです。インデントや改行が統一されているだけで、コードはかなり読みやすくなります。

4-1. インデントとスペースの基本ルール

C#では、インデントにスペース4つを使うスタイルが一般的です。

C#
public class UserService
{
public void Save(User user)
{
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}
}
}

演算子の前後にはスペースを入れると読みやすくなります。

C#
int totalPrice = price * quantity;

カンマの後にもスペースを入れます。

C#
CreateUser(name, age, email);

詰め込みすぎたコードは読みにくくなるため、適度にスペースを入れましょう。

4-2. 波かっこの書き方

C#では、波かっこを次の行に置く書き方がよく使われます。

C#
if (isActive)
{
SendEmail();
}

クラス、メソッド、if文、for文などでも同じスタイルにすると統一感が出ます。

C#
public class UserService
{
public void ActivateUser(User user)
{
if (!user.IsActive)
{
user.Activate();
}
}
}

チームによっては同じ行に波かっこを書くスタイルを採用することもありますが、C#では改行して書くスタイルが一般的です。

4-3. 1行の長さと改行位置の目安

1行が長すぎると、横スクロールが必要になり読みにくくなります。厳密な文字数はチームによりますが、100〜120文字程度を目安にするとよいでしょう。

長いメソッド呼び出しは、引数ごとに改行すると読みやすくなります。

C#
var user = CreateUser(
userName,
email,
birthDate,
address);

条件式が長い場合も、意味のまとまりで改行します。

C#
if (user.IsActive &&
user.HasPermission &&
!user.IsDeleted)
{
ShowDashboard();
}

無理に1行に詰め込まず、読みやすさを優先しましょう。

4-4. varを使うべき場面・使わない場面

C#ではvarを使うと、右辺から型を推論できます。

C#
var user = new User();

右辺を見れば型が明らかな場合は、varを使っても読みやすいです。

C#
var users = new List<User>();
var userService = new UserService();

一方、右辺だけでは型が分かりにくい場合は、明示的に型を書いたほうが読みやすくなります。

C#
User user = repository.FindById(userId);

varを使うかどうかは好みが分かれやすいポイントです。重要なのは、コードを読む人が型をすぐ理解できることです。

4-5. usingの並び順と不要なusingの整理

C#ファイルの先頭にはusingを記述します。

C#
using System;
using System.Collections.Generic;
using MyApp.Services;

不要なusingは削除しましょう。不要なusingが残っていると、コードの依存関係が分かりにくくなります。

Visual StudioやRiderなどのIDEには、不要なusingを自動で削除する機能があります。保存時や整形時に整理する設定にしておくと便利です。

4-6. コメントの書き方と書きすぎないコツ

コメントは、コードだけでは伝わりにくい意図を補足するために使います。何をしているかではなく、なぜそうしているかを書くと有用です。

悪い例です。

C#
// userIdが0以下か確認する
if (userId <= 0)
{
throw new ArgumentException("Invalid user id.");
}

コードを読めば分かる内容をコメントにしているだけです。

良い例です。

C#
// 外部システムでは未登録ユーザーを0として扱うため、ここで除外する
if (userId <= 0)
{
throw new ArgumentException("Invalid user id.");
}

コメントは多ければよいわけではありません。コード自体を分かりやすく書き、それでも補足が必要な場合にコメントを使いましょう。

4-7. XMLコメントを書くべき場面

publicなクラス、メソッド、プロパティにはXMLコメントを書くと、利用者に意図を伝えやすくなります。

C#
/// <summary>
/// 指定したIDのユーザーを取得します。
/// </summary>
/// <param name="userId">ユーザーID。</param>
/// <returns>ユーザー情報。</returns>
public User GetUserById(int userId)
{
return _userRepository.FindById(userId);
}

特にライブラリ、共通部品、APIとして外部から使われるコードではXMLコメントが役立ちます。一方、privateメソッドすべてに機械的にコメントを書く必要はありません。メソッド名を分かりやすくし、コメントがなくても読めるコードを目指しましょう。

5. 初心者が迷いやすいC#の書き方ルール

C#には多くのキーワードや構文があります。ここでは、初心者が特に迷いやすいpublicstaticreadonlyconstnull、例外処理、LINQ、async/awaitなどのルールを解説します。

5-1. public・private・protectedの使い分け

アクセス修飾子は、クラスやメンバーをどこから使えるかを決めるルールです。

publicは外部から利用できるメンバーに使います。

C#
public string Name { get; set; }

privateはクラス内部だけで使うメンバーに使います。

C#
private int _retryCount;

protectedは、そのクラス自身と継承先のクラスから使えるメンバーに使います。

C#
protected void WriteLog(string message)
{
}

基本は、できるだけ公開範囲を狭くすることです。必要がないものまでpublicにすると、後から変更しにくくなります。

5-2. staticの使いどころ

staticは、インスタンスを作らなくても使えるメンバーに付けます。

C#
public static class MathHelper
{
public static int Add(int x, int y)
{
return x + y;
}
}

状態を持たない便利メソッドや、共通処理にはstaticが向いています。

ただし、何でもstaticにするとテストしにくくなったり、依存関係を差し替えにくくなったりします。データベースアクセスや外部API通信など、差し替えが必要な処理はインスタンスとして扱ったほうが柔軟です。

5-3. readonly・constの使い分け

constはコンパイル時に値が決まる定数に使います。

C#
public const int MaxRetryCount = 3;

readonlyは、コンストラクターで設定した後に変更しないフィールドに使います。

C#
private readonly UserRepository _userRepository;

public UserService(UserRepository userRepository)
{
_userRepository = userRepository;
}

文字列や数値の固定値にはconst、依存オブジェクトや実行時に決まる値にはreadonlyを使うのが基本です。

5-4. nullを扱うときのルール

C#ではnullが原因でエラーになることがあります。特にNullReferenceExceptionは初心者がよく遭遇するエラーです。

引数にnullが来てはいけない場合は、早めにチェックします。

C#
public void Save(User user)
{
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}

_userRepository.Save(user);
}

C#ではnull許容参照型を使うことで、nullになる可能性を型で表現できます。

C#
string userName = "Taro";
string? nickName = null;

?が付いている型はnullになる可能性があることを示します。nullを許可するのか、許可しないのかを明確にすることが重要です。

5-5. 例外処理の書き方

例外処理では、握りつぶしを避けることが大切です。

悪い例です。

C#
try
{
SaveUser(user);
}
catch
{
}

これではエラーが起きても原因が分かりません。

良い例です。

C#
try
{
SaveUser(user);
}
catch (DatabaseException ex)
{
_logger.LogError(ex, "ユーザー保存中にエラーが発生しました。");
throw;
}

例外を捕まえる場合は、必要なログを残し、適切に再スローするか、呼び出し元に分かる形で処理しましょう。むやみにすべての例外をcatchするのは避けるべきです。

5-6. if文・switch文の書き方

if文では、条件が読みやすいことを重視します。

C#
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}

if (!user.IsActive)
{
return;
}

条件が複雑な場合は、変数に分けると読みやすくなります。

C#
bool canAccess = user.IsActive && user.HasPermission && !user.IsDeleted;

if (canAccess)
{
ShowPage();
}

switch文は、状態や種別によって処理を分けるときに便利です。

C#
switch (order.Status)
{
case OrderStatus.Pending:
CancelOrder(order);
break;

case OrderStatus.Paid:
RefundOrder(order);
break;

default:
throw new InvalidOperationException("Unsupported order status.");
}

分岐が増えすぎる場合は、設計を見直すサインかもしれません。

5-7. LINQを使うときの注意点

LINQを使うと、コレクション処理を簡潔に書けます。

C#
var activeUsers = users
.Where(user => user.IsActive)
.OrderBy(user => user.Name)
.ToList();

ただし、LINQを長くつなげすぎると読みにくくなります。

C#
var result = users.Where(u => u.IsActive).Select(u => u.Orders).SelectMany(o => o).Where(o => o.TotalPrice > 1000).OrderBy(o => o.CreatedAt).ToList();

このような場合は、改行したり、中間変数を使ったりしましょう。

C#
var activeUsers = users.Where(user => user.IsActive);

var expensiveOrders = activeUsers
.SelectMany(user => user.Orders)
.Where(order => order.TotalPrice > 1000)
.OrderBy(order => order.CreatedAt)
.ToList();

読みやすさを犠牲にしてまで短く書く必要はありません。

5-8. 非同期処理async/awaitの命名と書き方

非同期メソッドは、メソッド名の末尾にAsyncを付けるのが一般的です。

C#
public async Task<User> GetUserByIdAsync(int userId)
{
return await _userRepository.FindByIdAsync(userId);
}

戻り値は、値を返す場合はTask<T>、値を返さない場合はTaskにします。

C#
public async Task SaveUserAsync(User user)
{
await _userRepository.SaveAsync(user);
}

async voidは、基本的にイベントハンドラー以外では避けましょう。呼び出し元で完了や例外を扱いにくくなるためです。

6. C#の設計・保守性を高めるコーディングルール

C#のルールは、見た目を整えるだけではありません。長く保守できるコードにするためには、設計面のルールも重要です。

6-1. 1つのメソッドを長くしすぎない

メソッドが長すぎると、何をしているのか理解しにくくなります。1つのメソッドには、1つの目的を持たせるのが基本です。

悪い例です。

C#
public void RegisterUser(User user)
{
// 入力チェック
// 重複確認
// 保存処理
// メール送信
// ログ出力
}

処理が多い場合は、メソッドに分割します。

C#
public void RegisterUser(User user)
{
ValidateUser(user);
EnsureUserDoesNotExist(user);
SaveUser(user);
SendWelcomeEmail(user);
}

メソッド名が処理の流れを説明してくれるため、読みやすくなります。

6-2. 1つのクラスに責務を詰め込みすぎない

1つのクラスに多くの責務を詰め込むと、変更の影響範囲が大きくなります。

悪い例です。

C#
public class UserManager
{
public void ValidateUser(User user) { }
public void SaveUser(User user) { }
public void SendEmail(User user) { }
public void ExportCsv(List<User> users) { }
}

ユーザー検証、保存、メール送信、CSV出力が1つのクラスに入っており、責務が多すぎます。

分割例です。

C#
public class UserValidator
{
public void Validate(User user) { }
}

public class UserRepository
{
public void Save(User user) { }
}

public class EmailService
{
public void SendWelcomeEmail(User user) { }
}

クラスの責務を分けると、修正しやすくテストもしやすくなります。

6-3. マジックナンバーを避ける

意味の分からない数値を直接コードに書くことを、マジックナンバーと呼びます。

悪い例です。

C#
if (retryCount > 3)
{
throw new InvalidOperationException();
}

3が何を意味するのか分かりません。

良い例です。

C#
private const int MaxRetryCount = 3;

if (retryCount > MaxRetryCount)
{
throw new InvalidOperationException();
}

定数名を付けることで、数値の意味が明確になります。

6-4. 重複コードを減らす

同じような処理が複数箇所にあると、修正漏れの原因になります。

悪い例です。

C#
if (userName.Length > 50)
{
throw new ArgumentException("名前が長すぎます。");
}

if (displayName.Length > 50)
{
throw new ArgumentException("名前が長すぎます。");
}

共通処理にまとめます。

C#
private const int MaxNameLength = 50;

private void ValidateNameLength(string name)
{
if (name.Length > MaxNameLength)
{
throw new ArgumentException("名前が長すぎます。");
}
}

重複を減らすことで、変更に強いコードになります。

6-5. 早期returnでネストを浅くする

if文のネストが深いと、コードを追いにくくなります。条件を満たさない場合に早めにreturnすると、ネストを浅くできます。

悪い例です。

C#
public void SendEmail(User user)
{
if (user != null)
{
if (user.IsActive)
{
if (!string.IsNullOrEmpty(user.Email))
{
_emailService.Send(user.Email);
}
}
}
}

良い例です。

C#
public void SendEmail(User user)
{
if (user is null)
{
return;
}

if (!user.IsActive)
{
return;
}

if (string.IsNullOrEmpty(user.Email))
{
return;
}

_emailService.Send(user.Email);
}

条件が増えるほど、早期returnの効果は大きくなります。

6-6. 読みやすい条件式を書く

条件式は、読みやすさを優先しましょう。複雑な条件を1行に詰め込むと理解しにくくなります。

悪い例です。

C#
if ((user.IsActive && user.Age >= 20 && !user.IsDeleted) || user.IsAdmin)
{
ShowPage();
}

良い例です。

C#
bool isAdultActiveUser = user.IsActive && user.Age >= 20 && !user.IsDeleted;
bool canAccess = isAdultActiveUser || user.IsAdmin;

if (canAccess)
{
ShowPage();
}

条件に名前を付けることで、意図が明確になります。

6-7. テストしやすいコードにする

テストしやすいコードは、保守しやすいコードでもあります。外部依存を直接作るのではなく、コンストラクターで受け取るようにすると差し替えやすくなります。

悪い例です。

C#
public class UserService
{
private readonly UserRepository _repository = new UserRepository();
}

良い例です。

C#
public class UserService
{
private readonly IUserRepository _repository;

public UserService(IUserRepository repository)
{
_repository = repository;
}
}

インターフェースを使って依存関係を外から渡すことで、テスト時にモックへ差し替えやすくなります。

7. C#のコーディングルールを自動で守る方法

コーディングルールは、人間の注意だけで守り続けるのは大変です。Visual Studio、.editorconfig、Analyzer、dotnet format、CIなどを使って自動化すると、チーム全体で品質を保ちやすくなります。

7-1. Visual Studioのコード整形を使う

Visual Studioにはコード整形機能があります。インデント、スペース、改行などを自動で整えることができます。

よく使う操作は、ドキュメント全体のフォーマットです。コードの見た目が崩れたときは、自動整形を使うと簡単に整えられます。

ただし、整形ルールがチーム内で統一されていないと、人によって差が出ることがあります。そのため、次に紹介する.editorconfigを併用するのがおすすめです。

7-2. .editorconfigでルールを統一する

.editorconfigは、プロジェクトごとのコーディングスタイルを定義するためのファイルです。インデントサイズ、改行コード、varの使い方、命名規則などを設定できます。

例です。

INI
root = true

[*.cs]
indent_style = space
indent_size = 4

dotnet_sort_system_directives_first = true

dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion

csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = false:suggestion

.editorconfigをリポジトリに含めておくと、チーム全員が同じルールでコードを書きやすくなります。

7-3. Roslyn Analyzerを使う

Roslyn Analyzerは、C#のコードを解析して問題点を検出する仕組みです。命名規則、不要なコード、潜在的なバグ、パフォーマンス上の問題などを警告として表示できます。

Analyzerを導入すると、レビュー前に機械的な指摘を自動で受けられます。人間のレビューでは設計や仕様に集中し、形式的なチェックはツールに任せるのが効率的です。

7-4. StyleCop Analyzersを使う

StyleCop Analyzersは、C#のスタイルチェックを行うための代表的なAnalyzerです。命名規則、コメント、メンバーの並び順、空行など、細かいルールをチェックできます。

ただし、初期設定のままだと厳しすぎる場合があります。すべての警告を有効にするのではなく、プロジェクトに必要なルールだけを選んで使うとよいでしょう。

7-5. dotnet formatで自動整形する

dotnet formatを使うと、コマンドラインからコードを自動整形できます。

Bash
dotnet format

.editorconfigの設定に従って整形できるため、チーム開発やCIとの相性が良いです。

特定のソリューションを指定することもできます。

Bash
dotnet format MyApp.sln

手動で整形するだけでなく、コミット前やCIで実行すると、コードスタイルの乱れを防ぎやすくなります。

7-6. チーム開発でルールを共有する方法

チーム開発では、ルールを口頭で共有するだけでは不十分です。ドキュメント、.editorconfig、Analyzer設定、コードレビュー基準として明文化しましょう。

最低限、次の内容は決めておくと安心です。

命名規則、privateフィールドの書き方、varの使用方針、コメントの方針、例外処理の方針、1メソッドの長さの目安、コードレビューで見るポイントなどです。

ルールは細かすぎると守るのが大変になります。最初は重要な部分だけ決め、必要に応じて追加していくのがおすすめです。

7-7. CIでルール違反を検出する方法

CIでビルドやテストと一緒にコードチェックを行うと、ルール違反を早い段階で検出できます。

たとえば、CIで次のようなコマンドを実行します。

Bash
dotnet build
dotnet test
dotnet format --verify-no-changes

dotnet format --verify-no-changesを使うと、整形が必要なファイルがある場合に検出できます。これにより、整形漏れのあるコードがmainブランチに入るのを防ぎやすくなります。

8. C#コーディングルールの実例

ここでは、悪いコードを少しずつ改善しながら、C#の命名規則やコーディングルールを実例で確認します。

8-1. 悪いコード例

次のコードは動くかもしれませんが、読みやすいとはいえません。

C#
public class usermanager{
public void save(string n,int a){
if(n!=null){
if(a>0){
Console.WriteLine("save");
}
}
}
}

問題点は、クラス名がPascalCaseではない、メソッド名が小文字、引数名が分かりにくい、インデントがない、ネストが深い、処理内容が曖昧、などです。

8-2. 命名規則を直したコード例

まず、命名規則を直します。

C#
public class UserManager
{
public void Save(string userName, int age)
{
if (userName != null)
{
if (age > 0)
{
Console.WriteLine("save");
}
}
}
}

クラス名はUserManager、メソッド名はSave、引数名はuserNameageに変更しました。これだけでも、コードの意味が分かりやすくなります。

8-3. インデント・改行を整えたコード例

次に、インデントと改行を整えます。

C#
public class UserManager
{
public void Save(string userName, int age)
{
if (userName != null)
{
if (age > 0)
{
Console.WriteLine("save");
}
}
}
}

C#では、クラス、メソッド、if文のブロックごとに波かっこを改行して書くと読みやすくなります。インデントはスペース4つを基準にするとよいでしょう。

8-4. メソッド分割で読みやすくしたコード例

さらに、入力チェックを分けると意図が明確になります。

C#
public class UserManager
{
public void Save(string userName, int age)
{
if (!IsValidUser(userName, age))
{
return;
}

Console.WriteLine("save");
}

private bool IsValidUser(string userName, int age)
{
return !string.IsNullOrWhiteSpace(userName) && age > 0;
}
}

IsValidUserというメソッド名を見るだけで、ユーザー情報が有効かどうかを判定していることが分かります。また、早期returnによりネストも浅くなりました。

8-5. コメントと例外処理を改善したコード例

最後に、例外処理を追加して、より実務に近い形にします。

C#
public class UserService
{
private readonly IUserRepository _userRepository;
private readonly ILogger _logger;

public UserService(IUserRepository userRepository, ILogger logger)
{
_userRepository = userRepository;
_logger = logger;
}

public void Save(User user)
{
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}

if (!user.IsValid())
{
throw new ArgumentException("ユーザー情報が不正です。", nameof(user));
}

try
{
_userRepository.Save(user);
}
catch (Exception ex)
{
_logger.LogError(ex, "ユーザー保存中にエラーが発生しました。");
throw;
}
}
}

コメントを増やすのではなく、クラス名、メソッド名、変数名、例外メッセージで意図が伝わるようにしています。必要な場所で例外を投げ、ログも残しているため、問題が起きたときに原因を追いやすくなります。

9. C#初心者向けコーディングルールチェックリスト

C#のルールをすべて一度に覚えるのは大変です。まずは、次のチェックリストを使って、自分のコードを見直してみましょう。

9-1. 命名規則のチェック項目

クラス名はPascalCaseになっているか。

メソッド名はPascalCaseで、処理内容が分かる名前になっているか。

ローカル変数と引数はcamelCaseになっているか。

privateフィールドはチームのルールに従っているか。

bool型はIsHasCanなどで意味が分かる名前になっているか。

コレクションは複数形になっているか。

省略しすぎた名前や意味のない名前を使っていないか。

9-2. 書式・インデントのチェック項目

インデントは統一されているか。

波かっこの位置はプロジェクト内で統一されているか。

演算子の前後に適切なスペースがあるか。

1行が長くなりすぎていないか。

長い引数や条件式は適切に改行されているか。

不要なusingが残っていないか。

9-3. 可読性のチェック項目

メソッド名を見ただけで処理内容が分かるか。

条件式が複雑すぎないか。

ネストが深くなりすぎていないか。

コメントがコードの説明だけになっていないか。

コメントが古い情報になっていないか。

LINQを長くつなげすぎていないか。

9-4. 保守性のチェック項目

1つのメソッドに複数の責務が入っていないか。

1つのクラスに責務を詰め込みすぎていないか。

マジックナンバーを使っていないか。

重複コードがないか。

例外を握りつぶしていないか。

外部依存を差し替えにくい設計になっていないか。

テストしやすい構造になっているか。

9-5. チーム開発前に決めるべきルール

チーム開発を始める前に、最低限のC#コーディングルールを決めておきましょう。

命名規則、privateフィールドの接頭辞、varの使い方、コメントの書き方、例外処理の方針、フォーマット方法、Analyzerの導入有無、レビュー基準などを決めておくと、開発中の迷いが減ります。

また、ルールはドキュメントに書くだけでなく、.editorconfigやAnalyzerで自動的にチェックできるようにすると効果的です。

10. C#のルールに関するよくある質問

ここでは、C#の命名規則やコーディングルールについて、初心者がよく疑問に感じるポイントを解説します。

10-1. C#の命名規則は必ず守るべき?

C#の命名規則は、文法のように必ず守らないとコンパイルできないものではありません。しかし、実務では守るべき重要なルールです。

命名規則がバラバラだと、コードを読むたびに余計な判断が必要になります。特にチーム開発では、統一された命名規則があることでレビューや保守がしやすくなります。

個人開発でも、後から自分が読み返すことを考えると、基本的な命名規則は守るのがおすすめです。

10-2. privateフィールドにはアンダースコアを付けるべき?

privateフィールドにアンダースコアを付けるかどうかは、プロジェクトの方針によります。

よく使われる書き方は次の形式です。

C#
private readonly UserRepository _userRepository;

この書き方は、フィールドとローカル変数、コンストラクター引数を区別しやすいメリットがあります。

一方で、アンダースコアを使わずcamelCaseにするチームもあります。

C#
private readonly UserRepository userRepository;

どちらか一方に統一されていれば問題ありません。既存プロジェクトでは、すでに使われているスタイルに合わせましょう。

10-3. 定数名は大文字のスネークケースにする?

C#では、定数名もPascalCaseにするのが一般的です。

C#
public const int MaxRetryCount = 3;

JavaやC言語ではMAX_RETRY_COUNTのような大文字スネークケースが使われることがありますが、C#では標準的な書き方ではありません。

ただし、既存のコードベースで大文字スネークケースが採用されている場合は、プロジェクトの一貫性を優先しましょう。

10-4. varは使わないほうがいい?

varは使ってはいけないものではありません。右辺を見れば型が明らかな場合は、varを使うことでコードがすっきりします。

C#
var user = new User();
var users = new List<User>();

一方で、型が分かりにくい場合は明示的に書いたほうが読みやすくなります。

C#
User user = repository.FindById(userId);

varを使うかどうかは、読みやすさを基準に判断しましょう。チーム開発では、.editorconfigで方針を統一するのがおすすめです。

10-5. UnityのC#ルールは通常のC#と違う?

UnityでもC#を使いますが、Unity特有の書き方があります。たとえば、MonoBehaviourを継承したクラスでは、StartUpdateAwakeなど、Unityが呼び出すメソッド名が決まっています。

C#
public class PlayerController : MonoBehaviour
{
private void Start()
{
}

private void Update()
{
}
}

また、Unityエディター上で表示するために、privateフィールドに[SerializeField]を付けることもあります。

C#
[SerializeField]
private float moveSpeed = 5f;

基本的なC#の命名規則は同じですが、Unityのライフサイクルやエディター連携に合わせたルールも意識する必要があります。

10-6. 個人開発でもコーディングルールは必要?

個人開発でもコーディングルールは必要です。最初は自分だけが読むコードでも、数週間後や数か月後に見返すと、意外と内容を忘れているものです。

命名規則やインデントが整っているだけで、修正や機能追加が楽になります。特に、将来的にチーム開発へ移行する可能性がある場合は、最初から基本的なルールを守っておくとスムーズです。

10-7. C#のコーディングルールはどこまで厳密に決めるべき?

C#のコーディングルールは、厳密にしすぎると開発の負担になります。一方で、何も決めないとコードがバラバラになります。

最初は、命名規則、インデント、varの使い方、privateフィールドの書き方、例外処理、コメント方針など、影響の大きい部分から決めるのがおすすめです。

細かいルールは、開発中に迷いや問題が出たタイミングで追加していけば十分です。重要なのは、完璧なルールを作ることではなく、チーム全体で一貫したコードを書ける状態にすることです。

まとめ

C#のルールには、文法ルールだけでなく、命名規則、書式ルール、設計ルールなどがあります。文法として正しいコードでも、命名が分かりにくかったり、インデントが乱れていたり、責務が詰め込まれすぎていたりすると、保守しづらいコードになってしまいます。

C#の命名規則では、クラス名、メソッド名、プロパティ名はPascalCase、ローカル変数や引数はcamelCase、privateフィールドは_ camelCaseを使うスタイルがよく使われます。bool型にはIsHasCanなどを付け、コレクションは複数形にすると意味が伝わりやすくなります。

コーディングルールでは、インデント、波かっこ、改行、usingの整理、コメントの書き方、例外処理などを統一することが大切です。また、メソッドを短くする、クラスの責務を分ける、マジックナンバーや重複コードを避けるといった設計面のルールも、保守性を高めるために欠かせません。

ルールを人間の注意だけで守るのは大変です。Visual Studioの整形機能、.editorconfig、Roslyn Analyzer、StyleCop Analyzers、dotnet format、CIを活用して、自動的にチェックできる仕組みを作りましょう。

初心者のうちは、すべてを完璧に覚える必要はありません。まずは「名前を分かりやすくする」「インデントを整える」「メソッドを長くしすぎない」「チームのルールに合わせる」という基本から始めることが大切です。C#のコーディングルールを意識して書くことで、読みやすく、保守しやすく、長く使えるコードに近づけます。