C#コーディング規約の基本|命名規則から保守しやすい書き方まで初心者向けに解説
はじめに
C#コーディングで大切なのは、単に「動くコード」を書くことではありません。あとから読んでも意図が分かり、修正しやすく、他の開発者が迷わず扱えるコードにすることが重要です。
特に初心者のうちは、文法を覚えることに意識が向きがちですが、実務では「読みやすいか」「保守しやすいか」「チームで同じ書き方になっているか」が重視されます。C#には命名規則、インデント、コメント、例外処理、非同期処理など、守っておきたい基本的なコーディング規約があります。
この記事では、C#コーディング規約の基本を、命名規則から保守しやすい書き方、初心者がやりがちなNG例、便利なツールまで順番に解説します。
1. C#コーディング規約とは?初心者が最初に理解すべき基本
C#コーディング規約とは、C#のコードを書くときに守るルールや方針のことです。たとえば、クラス名をどのように書くか、変数名をどう付けるか、波括弧をどこに置くか、コメントをどの程度書くかといった内容が含まれます。
コーディング規約は、コードの見た目をそろえるためだけのものではありません。コードを読みやすくし、バグを見つけやすくし、修正や機能追加をしやすくするための実践的なルールです。
MicrosoftのC#関連ドキュメントでも、コードの可読性、一貫性、共同作業のしやすさを保つためにコーディング規約が重要だと説明されています。C#プログラムでは、型名や名前空間、publicメンバーにPascalCaseを使うなど、一般的な命名規則も示されています。
1-1. コーディング規約の目的は「読みやすく保守しやすいコード」にすること
コーディング規約の最大の目的は、コードを読みやすく保守しやすくすることです。
たとえば、次のようなコードは動作するかもしれませんが、読みやすいとは言えません。
C#public int calc(int a,int b){return a*b+100;}
処理が短い場合でも、名前や空白が分かりにくいと、後から見たときに「何を計算しているのか」が分かりません。
改善すると、次のようになります。
C#public int CalculateTotalPrice(int unitPrice, int quantity)
{
const int ShippingFee = 100;
return unitPrice * quantity + ShippingFee;
}
このコードであれば、単価と数量から合計金額を計算し、送料を加えていることが分かります。C#コーディングでは、コンピューターに理解させるだけでなく、人間が理解しやすい形で書くことが大切です。
1-2. C#で規約が重要になる理由
C#は、Webアプリケーション、デスクトップアプリ、ゲーム開発、クラウドアプリなど幅広い分野で使われます。小さな学習用プログラムであれば自分だけが読めれば問題ないかもしれませんが、実務では長期間にわたって多くの人がコードを触ります。
C#ではクラス、インターフェイス、プロパティ、LINQ、非同期処理、Nullable Reference Typesなど、コードを表現する方法が豊富です。自由度が高い分、書き方がバラバラになると、コード全体の理解が難しくなります。
たとえば、あるクラスではGetUserName、別のクラスではget_user_name、さらに別の場所ではGetUsrNmのように書かれていると、同じ意味の処理なのか判断しにくくなります。規約を決めておくことで、コードを読むときの迷いを減らせます。
1-3. 個人開発とチーム開発で規約の役割はどう変わるか
個人開発では、自分が理解しやすいルールを決めておくだけでも十分効果があります。命名やインデントを統一しておけば、数週間後や数か月後にコードを見直したときに理解しやすくなります。
一方、チーム開発では、規約はさらに重要になります。自分にとって分かりやすい書き方でも、他のメンバーにとって分かりやすいとは限りません。チームで同じルールを共有しておくことで、レビュー時の指摘が減り、本質的な設計やバグの確認に集中できます。
チーム開発におけるC#コーディング規約は、「誰が書いても同じように読めるコード」を目指すための共通言語です。
1-4. コーディング規約・コーディングルール・スタイルガイドの違い
コーディング規約、コーディングルール、スタイルガイドは似た意味で使われますが、少しニュアンスが異なります。
コーディング規約は、命名、レイアウト、設計方針などを含む広いルールです。コーディングルールは、より具体的な禁止事項や必須事項を指すことが多く、「例外を握りつぶさない」「publicを安易に使わない」といった内容が該当します。
スタイルガイドは、主に見た目や書き方の統一に関するガイドです。インデント、空白、改行、波括弧の位置、命名規則などが中心になります。
実際の開発現場では、これらを厳密に分けるよりも、「チームで守るC#コーディングのルール」としてまとめて扱うことが多いです。
2. C#コーディングで守りたい命名規則の基本
命名規則は、C#コーディング規約の中でも特に重要です。名前が分かりやすいだけで、コードの理解しやすさは大きく変わります。
良い名前は、コメントがなくても役割が伝わります。逆に悪い名前は、処理を一行ずつ読まなければ意味が分かりません。
C#では、クラス名やメソッド名にはPascalCase、ローカル変数や引数にはcamelCaseを使うのが一般的です。Microsoftのドキュメントでも、クラス名・メソッド名にはPascalCase、ローカル変数やメソッド引数にはcamelCaseを使う規約が示されています。
2-1. クラス名・構造体名はPascalCaseで書く
クラス名や構造体名は、PascalCaseで書くのが基本です。PascalCaseとは、単語の先頭を大文字にしてつなげる書き方です。
C#public class UserService
{
}
public struct MoneyAmount
{
}
悪い例は次のような命名です。
C#public class userservice
{
}
public class user_service
{
}
C#では、クラス名は「何を表すものか」が分かる名詞にするのが自然です。UserService、OrderRepository、PaymentResultのように、役割が伝わる名前を付けましょう。
2-2. メソッド名・プロパティ名はPascalCaseで書く
メソッド名とプロパティ名もPascalCaseで書きます。
C#public string UserName { get; set; }
public decimal CalculateTotalPrice()
{
return 0;
}
メソッド名は、処理を表す動詞または動詞句にすると分かりやすくなります。
C#GetUser()
CreateOrder()
CalculateTotalPrice()
SendEmail()
プロパティ名は、値の意味を表す名詞にします。
C#UserName
TotalPrice
CreatedAt
IsActive
メソッドは「何をするか」、プロパティは「何を表すか」を意識して命名すると、自然なC#コードになります。
2-3. 変数名・引数名・ローカル関数名はcamelCaseで書く
ローカル変数やメソッドの引数は、camelCaseで書くのが基本です。camelCaseとは、最初の単語を小文字で始め、2語目以降の先頭を大文字にする書き方です。
C#public void UpdateUserName(string userName)
{
int retryCount = 0;
string normalizedName = userName.Trim();
}
ただし、ローカル関数名については注意が必要です。チーム規約としてcamelCaseを採用する場合もありますが、Microsoftの現在のC#識別子規約では、メソッドとローカル関数はPascalCaseで書く例が示されています。既存プロジェクトにルールがある場合は、そのルールに合わせることを優先しましょう。
C#public void Process()
{
int CalculateScore(int baseScore)
{
return baseScore + 10;
}
int score = CalculateScore(90);
}
重要なのは、camelCaseかPascalCaseかを場当たり的に混ぜないことです。プロジェクト全体で統一されていれば、読み手の負担を減らせます。
2-4. インターフェイス名にはIを付ける
C#では、インターフェイス名の先頭にIを付けるのが一般的です。
C#public interface IUserRepository
{
User FindById(int id);
}
IUserRepositoryという名前を見るだけで、クラスではなくインターフェイスであることが分かります。Microsoftの命名規則でも、インターフェイス名にはPascalCaseを使い、先頭にIを付ける規約が示されています。
悪い例は次のような命名です。
C#public interface UserRepositoryInterface
{
}
意味は分かりますが、C#では冗長に見えます。一般的な慣習に合わせてIUserRepositoryとする方が自然です。
2-5. 定数・読み取り専用フィールドの命名ルール
C#の定数は、PascalCaseで書くのが一般的です。
C#public const int MaxRetryCount = 3;
private const decimal TaxRate = 0.1m;
他の言語ではMAX_RETRY_COUNTのように大文字とアンダースコアで書くことがありますが、C#ではPascalCaseがよく使われます。
読み取り専用フィールドの場合は、アクセス修飾子によって方針が変わることがあります。privateフィールドでは、先頭にアンダースコアを付けたcamelCaseを使う規約も一般的です。
C#private readonly ILogger _logger;
private readonly IUserRepository _userRepository;
一方、publicな定数やpublicな読み取り専用メンバーはPascalCaseにするのが自然です。
C#public static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30);
定数やreadonlyフィールドは、プロジェクト内でルールを決めて統一することが大切です。
2-6. bool型の変数名は意味が伝わる形にする
bool型の変数名は、trueまたはfalseの意味がすぐ分かる名前にしましょう。
良い例は次のような名前です。
C#bool isActive;
bool hasPermission;
bool canExecute;
bool shouldRetry;
悪い例は次のような名前です。
C#bool flag;
bool check;
bool status;
flagやcheckだけでは、trueのときに何を意味するのか分かりません。
条件文で読んだときに自然な名前にすると、コードが分かりやすくなります。
C#if (hasPermission)
{
Execute();
}
このように書けば、「権限がある場合に実行する」という意味がすぐに伝わります。
2-7. 略語や省略名を避けて意図が伝わる名前にする
変数名やメソッド名は、短ければよいわけではありません。むしろ、意味が分からない省略名は避けるべきです。
C#// 悪い例
int cnt;
string usrNm;
decimal amt;
改善すると、次のようになります。
C#int userCount;
string userName;
decimal amount;
Microsoftの命名ガイドラインでも、読みやすい識別子名を選ぶこと、短さよりも分かりやすさを優先すること、略語や省略形を避けることが推奨されています。
ただし、id、url、htmlのように広く使われている略語は、チーム内で許容されることが多いです。大切なのは、初見の人でも意味が分かるかどうかです。
2-8. 悪い命名例と改善例
命名の良し悪しは、比較すると分かりやすくなります。
C#// 悪い例
public void DoIt(int x)
{
var y = x * 1.1m;
Console.WriteLine(y);
}
このコードは、DoItが何をするのか、xやyが何を表すのか分かりません。
改善例は次のとおりです。
C#public void PrintPriceIncludingTax(decimal price)
{
const decimal TaxRate = 0.1m;
decimal priceIncludingTax = price * (1 + TaxRate);
Console.WriteLine(priceIncludingTax);
}
処理内容はほぼ同じでも、名前を変えるだけでコードの意図が明確になります。C#コーディングでは、名前そのものを小さな説明文として使う意識が大切です。
3. 読みやすいC#コードにするための書き方
読みやすいC#コードを書くには、命名だけでなく、インデント、空白、改行、コメント、ネストの深さなどにも気を配る必要があります。
コードの見た目が整っていると、処理の構造が理解しやすくなります。逆に、見た目が乱れているコードは、たとえ処理が正しくても、レビューや保守に時間がかかります。
3-1. インデント・空白・改行を統一する
C#では、インデントにスペース4つを使うスタイルがよく使われます。MicrosoftのC#コード規約でも、タブではなくスペース4つによるインデント、1行1ステートメント、1行1宣言などのレイアウト方針が示されています。
悪い例です。
C#public void Save(User user){
if(user == null){
throw new ArgumentNullException(nameof(user));
}
_repository.Save(user);}
改善例です。
C#public void Save(User user)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
_repository.Save(user);
}
インデントが整っていると、if文の範囲やメソッドの範囲が一目で分かります。空行も適度に入れると、処理のまとまりが見えやすくなります。
3-2. 1行に詰め込みすぎない
1行に多くの処理を詰め込むと、コードが読みにくくなります。
C#if (user != null && user.IsActive && user.HasPermission && user.LastLoginDate > limitDate) SendNotification(user);
短く見えるかもしれませんが、条件が増えるほど読みづらくなります。
改善例です。
C#bool shouldSendNotification =
user != null
&& user.IsActive
&& user.HasPermission
&& user.LastLoginDate > limitDate;
if (shouldSendNotification)
{
SendNotification(user);
}
条件に名前を付けることで、何を判断しているのか分かりやすくなります。C#コーディングでは、短さよりも理解しやすさを優先しましょう。
3-3. 波括弧の位置を統一する
C#では、波括弧を改行して置くAllmanスタイルがよく使われます。
C#public void Execute()
{
if (CanExecute())
{
Run();
}
}
次のような書き方も文法上は正しいですが、同じプロジェクト内で混在すると読みにくくなります。
C#public void Execute() {
if (CanExecute()) {
Run();
}
}
どちらを採用するかはチームの判断ですが、C#ではAllmanスタイルが多くのサンプルで使われています。重要なのは、同じプロジェクト内で波括弧の位置を統一することです。
3-4. varを使う場面と型を明示する場面を分ける
C#ではvarを使うと、右辺から型を推論できます。
C#var user = new User();
var message = "Hello";
型が明らかな場合は、varを使うとコードがすっきりします。一方、右辺を見ても型が分かりにくい場合は、型を明示した方が読みやすくなります。
C#// 型が分かりにくい
var result = repository.Find(id);
// 型を明示した方が親切
User? user = repository.Find(id);
MicrosoftのC#コード規約でも、右辺から型が明らかな場合は暗黙的な型付けを使い、型が明らかでない場合はvarを避ける方針が説明されています。LINQでは匿名型などの理由でvarが読みやすい場面もあります。
3-5. コメントは「何をしているか」ではなく「なぜそうするか」を書く
コメントは多ければよいわけではありません。コードを読めば分かることをコメントに書くと、かえってノイズになります。
C#// userNameを取得する
string userName = user.Name;
このコメントは、コードを見れば分かるため不要です。
良いコメントは、「なぜその処理が必要なのか」を説明します。
C#// 外部APIの仕様により、名前の前後の空白は送信前に除去する必要がある。
string userName = user.Name.Trim();
このコメントは、処理の背景を説明しています。将来の開発者が「なぜTrimしているのか」を理解しやすくなります。
3-6. マジックナンバーを避けて定数化する
コード中に意味の分からない数値が直接書かれていると、後から読んだときに意図が分かりません。
C#if (retryCount >= 3)
{
throw new InvalidOperationException();
}
3が何を意味するのか分かりにくいため、定数化します。
C#private const int MaxRetryCount = 3;
if (retryCount >= MaxRetryCount)
{
throw new InvalidOperationException();
}
定数名を付けることで、数値の意味が明確になります。値を変更するときも、定数の定義箇所を修正するだけで済みます。
3-7. ネストを深くしすぎない
ネストが深いコードは、条件を追いかけるのが難しくなります。
C#public void Process(User user)
{
if (user != null)
{
if (user.IsActive)
{
if (user.HasPermission)
{
Execute(user);
}
}
}
}
早期returnを使うと、ネストを浅くできます。
C#public void Process(User? user)
{
if (user == null)
{
return;
}
if (!user.IsActive)
{
return;
}
if (!user.HasPermission)
{
return;
}
Execute(user);
}
ネストを浅くすると、正常系の処理が読みやすくなります。特に業務ロジックでは条件が増えやすいため、早期returnやメソッド分割を活用しましょう。
4. 保守しやすいC#コードにする設計・実装ルール
保守しやすいC#コードにするには、見た目の統一だけでは不十分です。メソッドやクラスの責務、重複コード、例外処理、null対策、非同期処理など、設計と実装の考え方も重要です。
保守しにくいコードは、最初は動いていても、変更のたびにバグを生みやすくなります。将来の変更に強いコードを書くことが、実務でのC#コーディングでは大切です。
4-1. メソッドは1つの責務に絞る
1つのメソッドに複数の役割を詰め込むと、修正しにくくなります。
C#public void RegisterUser(User user)
{
Validate(user);
SaveToDatabase(user);
SendWelcomeEmail(user);
WriteLog(user);
}
この例では、登録処理、検証、保存、メール送信、ログ出力が混ざっています。さらに処理が増えると、メソッドが肥大化します。
役割ごとに分けると、テストや修正がしやすくなります。
C#public void RegisterUser(User user)
{
ValidateUser(user);
SaveUser(user);
SendWelcomeEmail(user);
WriteRegistrationLog(user);
}
各メソッドが1つの責務に集中していれば、どこを修正すべきか判断しやすくなります。
4-2. クラスの役割を明確にする
クラスもメソッドと同じく、役割を明確にすることが重要です。
たとえば、UserServiceクラスにユーザー登録、メール送信、CSV出力、画面表示、ログ保存などをすべて詰め込むと、何でもできる代わりに何を担当しているのか分からないクラスになります。
役割ごとに分けると、保守しやすくなります。
C#public class UserService
{
private readonly IUserRepository _userRepository;
private readonly IEmailSender _emailSender;
public UserService(IUserRepository userRepository, IEmailSender emailSender)
{
_userRepository = userRepository;
_emailSender = emailSender;
}
}
UserServiceはユーザー関連の業務処理を担当し、保存はIUserRepository、メール送信はIEmailSenderに任せる形です。クラスの責務が分かれていると、変更の影響範囲を小さくできます。
4-3. 重複コードを避ける
同じようなコードが複数箇所にあると、修正漏れが起きやすくなります。
C#decimal priceWithTax1 = price1 * 1.1m;
decimal priceWithTax2 = price2 * 1.1m;
decimal priceWithTax3 = price3 * 1.1m;
消費税率が変わった場合、すべての箇所を修正しなければなりません。
共通メソッドにまとめると、変更に強くなります。
C#private const decimal TaxRate = 0.1m;
public decimal CalculatePriceIncludingTax(decimal price)
{
return price * (1 + TaxRate);
}
重複コードを見つけたら、「共通化できないか」「名前を付けて意味を表現できないか」を考えましょう。
4-4. 例外処理を適切に書く
例外処理は、エラーを隠すためではなく、適切に検知して対応するために書きます。
悪い例です。
C#try
{
Save(user);
}
catch
{
}
このように例外を握りつぶすと、問題が起きても原因が分からなくなります。
改善例です。
C#try
{
Save(user);
}
catch (IOException ex)
{
_logger.LogError(ex, "ユーザー情報の保存に失敗しました。");
throw;
}
例外を捕捉する場合は、必要なログを残し、呼び出し元に伝えるべき例外は再スローします。何でもcatchするのではなく、想定できる例外を具体的に扱うことが大切です。
4-5. nullチェックとNullable Reference Typesを意識する
C#では、null参照による実行時エラーを防ぐために、Nullable Reference Typesを活用できます。Nullable Reference Typesでは、stringとstring?のように、nullを許可するかどうかの意図をコード上に表現できます。Microsoftのドキュメントでも、null許容参照型は「どの変数をnullにできるか」という意図を示し、コンパイラがnull逆参照の可能性を警告すると説明されています。
C#public void PrintName(string? name)
{
if (name == null)
{
return;
}
Console.WriteLine(name.Length);
}
string?はnullの可能性があることを示します。そのため、使用前にnullチェックを行います。
一方、nullを許可しない設計にできる場合は、そもそもnullを受け取らないようにします。
C#public class User
{
public required string Name { get; init; }
}
null対策は、後から場当たり的にif文を増やすよりも、型や設計で意図を表すことが重要です。
4-6. LINQは読みやすさを優先して使う
LINQはC#らしい便利な機能ですが、使いすぎると読みにくくなる場合があります。
C#var result = users.Where(x => x.IsActive).OrderBy(x => x.Name).Select(x => x.Email).ToList();
短い場合は問題ありませんが、条件が複雑になるなら改行した方が読みやすくなります。
C#var activeUserEmails = users
.Where(user => user.IsActive)
.OrderBy(user => user.Name)
.Select(user => user.Email)
.ToList();
LINQでは、xのような短い名前が使われることもありますが、処理が複雑な場合はuserやorderのように意味のある名前を使いましょう。MicrosoftのC#コード規約でも、LINQのクエリ変数には意味のある名前を使うことが示されています。
4-7. 非同期処理ではasync/awaitの命名と使い方に注意する
C#の非同期処理では、asyncとawaitを使います。非同期メソッド名にはAsyncサフィックスを付けるのが一般的です。
C#public async Task<User> GetUserAsync(int userId)
{
return await _userRepository.FindByIdAsync(userId);
}
MicrosoftのTask-based Asynchronous Patternの説明でも、非同期メソッド名は慣例としてAsyncで終わること、戻り値には通常TaskまたはTask<TResult>を使うことが示されています。
避けたいのは、非同期処理を同期的に待つ書き方です。
C#// 避けたい例
var user = GetUserAsync(id).Result;
ResultやWait()を安易に使うと、デッドロックやパフォーマンス問題の原因になることがあります。基本的には、呼び出し元までasync/awaitでつなげて書きましょう。
5. C#初心者がやりがちなコーディングのNG例
C#初心者が書くコードには、よくあるNGパターンがあります。これらは文法エラーにはならないため、気づきにくいのが厄介です。
ここでは、C#コーディングで避けたい代表的な例を紹介します。
5-1. 意味のない変数名を使う
初心者がやりがちなのが、a、b、tmp、dataのような意味の薄い名前を多用することです。
C#var data = GetData();
var tmp = data.Count();
このコードでは、何のデータで、何を数えているのか分かりません。
改善例です。
C#var activeUsers = GetActiveUsers();
int activeUserCount = activeUsers.Count();
名前を具体的にするだけで、コードの意図が分かりやすくなります。
5-2. 1つのメソッドに処理を詰め込みすぎる
1つのメソッドが長くなりすぎると、処理の流れを追うのが難しくなります。入力チェック、計算、データ保存、メール送信、ログ出力などが1つのメソッドに混在している場合は、分割を検討しましょう。
C#public void CompleteOrder(Order order)
{
ValidateOrder(order);
CalculateTotalAmount(order);
SaveOrder(order);
SendOrderCompletedEmail(order);
}
このように、処理のまとまりごとにメソッド化すると、読みやすくテストしやすいコードになります。
5-3. コメントを書きすぎる・書かなすぎる
コメントを書きすぎると、コードが読みにくくなります。一方で、まったく書かないと、複雑な判断の理由が伝わりません。
悪いコメントの例です。
C#// iを1増やす
i++;
このコメントは不要です。
良いコメントの例です。
C#// 旧システムとの互換性維持のため、削除済みユーザーも検索対象に含める。
var users = FindUsers(includeDeleted: true);
コードから分かることではなく、背景や理由を書くのが良いコメントです。
5-4. 例外を握りつぶす
例外を空のcatchで握りつぶすのは避けましょう。
C#try
{
ImportFile(filePath);
}
catch
{
}
これでは、ファイルの読み込みに失敗しても原因が分かりません。
改善例です。
C#try
{
ImportFile(filePath);
}
catch (IOException ex)
{
_logger.LogError(ex, "ファイルのインポートに失敗しました。FilePath: {FilePath}", filePath);
throw;
}
例外は、必要に応じてログを残し、処理を継続できない場合は呼び出し元に伝えます。
5-5. publicを安易に使いすぎる
初心者のうちは、すべてのクラスやメソッドをpublicにしてしまいがちです。しかし、公開範囲が広いほど、変更の影響範囲も広がります。
C#public void CalculateInternalValue()
{
}
外部から呼び出す必要がないなら、privateにします。
C#private void CalculateInternalValue()
{
}
アクセス修飾子は、必要最小限にするのが基本です。外部に公開する必要があるものだけをpublicにしましょう。
5-6. 既存の規約と違う書き方を混在させる
既存プロジェクトでは、すでに命名やインデントのルールが決まっていることがあります。そこに自分だけ別の書き方を混ぜると、コード全体の一貫性が崩れます。
たとえば、既存コードが次のような命名で統一されているとします。
C#private readonly IUserRepository _userRepository;
そこに、次のような書き方を混在させると違和感が出ます。
C#private readonly IUserRepository userRepository;
どちらが絶対に正しいというより、同じプロジェクト内で統一されていることが重要です。新しいコードを書く前に、周囲のコードのスタイルを確認しましょう。
5-7. NGコードを改善する具体例
NGコードの例です。
C#public void Do(User u)
{
try
{
if (u != null)
{
if (u.IsActive)
{
var x = u.Name.Trim();
Console.WriteLine(x);
}
}
}
catch
{
}
}
問題点は、メソッド名が曖昧、引数名が短すぎる、ネストが深い、変数名が意味を持たない、例外を握りつぶしていることです。
改善例です。
C#public void PrintActiveUserName(User? user)
{
if (user == null)
{
return;
}
if (!user.IsActive)
{
return;
}
string trimmedUserName = user.Name.Trim();
Console.WriteLine(trimmedUserName);
}
処理が明確になり、ネストも浅くなりました。もしConsole.WriteLineで例外が発生する可能性に対応する必要がある場合は、具体的な例外を捕捉してログを残します。
6. C#コーディング規約を実践するためのチェックポイント
C#コーディング規約は、知っているだけでは意味がありません。日々の開発で確認できるチェックポイントに落とし込むことが大切です。
コードを書いた後やレビュー前に、次の観点で見直しましょう。
6-1. 命名規則が統一されているか
クラス名、メソッド名、プロパティ名、変数名、引数名が規約どおりになっているか確認します。
特に次の点を見直しましょう。
C#// クラス名・メソッド名・プロパティ名
UserService
CalculateTotalPrice
CreatedAt
// 変数名・引数名
userName
totalPrice
createdAt
意味のない省略名や、表記ゆれがないかも確認します。userNameとusername、customerIdとcustomerIDのような違いは、チーム内でルールを決めて統一しましょう。
6-2. インデントや改行が整っているか
インデントや改行が乱れていると、処理の構造が分かりにくくなります。Visual Studioなどのコード整形機能を使い、フォーマットをそろえましょう。
確認すべきポイントは、波括弧の位置、空行の使い方、1行の長さ、メソッド間の空行などです。自分の好みで手作業調整するより、ツールで自動整形できる状態にしておくと安定します。
6-3. メソッドやクラスの責務が明確か
メソッド名を見て、何をする処理か分かるか確認しましょう。もし説明しにくい場合、そのメソッドは複数の責務を持っている可能性があります。
クラスについても同じです。Manager、Helper、Commonのような曖昧な名前が増えている場合は、責務がぼやけていないか見直しましょう。
C#// 曖昧
public class UserHelper
{
}
// 役割が分かりやすい
public class UserRegistrationService
{
}
6-4. 不要なコメントや重複コードがないか
コードを読めば分かるコメントは削除し、なぜその処理が必要なのかを説明するコメントだけを残します。
また、似たような処理が複数箇所にないか確認しましょう。同じロジックがコピーされている場合、将来の修正漏れにつながります。
共通化する際は、無理に抽象化しすぎないことも大切です。2回出てきただけで必ず共通化するのではなく、変更理由が同じかどうかを考えて判断しましょう。
6-5. 例外処理やnull対策が適切か
例外を握りつぶしていないか、必要なログを残しているか、想定外のnullで落ちないかを確認します。
C#if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
引数としてnullを許可しないなら、早い段階で例外を投げる方が原因を特定しやすくなります。nullを許可するなら、User?のように型で意図を表し、使用前にチェックしましょう。
6-6. チーム内で同じルールを共有できているか
規約は、ドキュメント化されていなければ定着しません。口頭だけで伝えると、人によって解釈が変わります。
最低限、次のような内容はチームで共有しておくとよいでしょう。
命名規則
インデントと改行
varの使用方針例外処理の方針
nullの扱い
コメントの書き方
レビュー時の指摘基準
ルールを決めたら、EditorConfigやAnalyzerなどのツールで自動チェックできる部分は自動化しましょう。
7. C#コーディング規約を効率よく守るためのツール
C#コーディング規約をすべて人の目だけでチェックするのは大変です。インデントや命名、不要なusing、コードスタイルの違反などは、ツールに任せることで効率化できます。
人がレビューすべきなのは、設計の妥当性、責務の分け方、業務ロジックの正しさなど、機械的に判断しにくい部分です。
7-1. Visual Studioのコード整形機能を使う
Visual Studioには、コードの整形やCode Cleanup機能があります。インデント、空白、usingの整理などを自動で整えられるため、手作業でフォーマットをそろえる手間を減らせます。
C#初心者は、まずコードを書いた後に整形を実行する習慣を付けるとよいでしょう。見た目が整うだけでも、コードレビューで指摘される基本的なミスを減らせます。
7-2. EditorConfigでルールを統一する
EditorConfigを使うと、インデント、改行、命名規則、コードスタイルなどをプロジェクト単位で定義できます。Microsoftのドキュメントでも、.editorconfigファイルでクラス、プロパティ、メソッドなどの命名規則と、それに違反した場合の重大度を設定できると説明されています。
たとえば、次のようなルールを設定できます。
INIroot = true
[*.cs]
indent_style = space
indent_size = 4
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
EditorConfigをリポジトリに含めておけば、メンバーごとのエディタ設定に依存せず、チーム全体で同じルールを共有できます。
7-3. StyleCop Analyzersで規約違反を検出する
StyleCop Analyzersは、C#コードのスタイル違反を検出するためのAnalyzerです。GitHub上の公式リポジトリでは、.NET Compiler Platformを使ってStyleCopルールを実装し、可能な場合は修正支援も提供すると説明されています。
StyleCop Analyzersを導入すると、命名、コメント、レイアウトなどの違反をビルド時やエディタ上で検出できます。
ただし、最初からすべてのルールを厳格に有効にすると、警告が多すぎて開発が進みにくくなることがあります。まずはチームに必要なルールだけを有効にし、段階的に強化するのがおすすめです。
7-4. Roslyn Analyzerでコード品質を確認する
Roslyn Analyzerは、C#やVisual Basicのコードを解析し、スタイル、品質、保守性、設計上の問題などを検出する仕組みです。MicrosoftのVisual Studioドキュメントでは、Roslyn AnalyzerがC#またはVisual Basicコードを検査し、コードスタイルや品質などの問題を分析すると説明されています。
たとえば、次のような問題を検出できます。
未使用の変数
到達不能コード
nullの可能性
不適切な例外処理
パフォーマンス上の問題
命名やスタイルの違反
.NETのコード分析では、セキュリティ、パフォーマンス、設計などに関するコード品質ルールも提供されています。
7-5. GitHubやCIで自動チェックする
ローカル環境だけで規約チェックをしていると、設定漏れや実行忘れが起きることがあります。そのため、GitHub ActionsなどのCIで自動チェックするのが効果的です。
たとえば、プルリクエスト作成時に次のようなチェックを実行できます。
Bashdotnet build
dotnet test
dotnet format --verify-no-changes
CIで自動チェックすれば、規約違反やフォーマット崩れをマージ前に検出できます。レビュー担当者が細かいフォーマット指摘に時間を使わず、設計やロジックの確認に集中できるようになります。
7-6. ツールに任せる部分と人がレビューすべき部分
ツールに任せるべきなのは、機械的に判断できる部分です。
たとえば、インデント、空白、改行、不要なusing、命名規則、単純なコードスタイル違反などはツールで検出できます。
一方で、人がレビューすべきなのは、次のような観点です。
メソッドやクラスの責務は適切か
仕様を正しく満たしているか
将来の変更に耐えられる設計か
エラーハンドリングの方針は妥当か
名前が業務上の意味を正しく表しているか
C#コーディング規約を効率よく守るには、「ツールで自動化する部分」と「人が考えて判断する部分」を分けることが重要です。
8. C#コーディング規約をチームに定着させるコツ
コーディング規約は、作っただけでは定着しません。現場で使われ続ける形にする必要があります。
規約が細かすぎたり、現実の開発に合っていなかったりすると、次第に守られなくなります。チームにとって実用的で、更新しやすい規約にすることが大切です。
8-1. 最初から細かすぎるルールを作らない
最初から細かいルールを大量に作ると、メンバーが覚えきれず、運用が重くなります。
最初は、次のような基本ルールから始めるのがおすすめです。
クラス名、メソッド名、プロパティ名はPascalCase
ローカル変数と引数はcamelCase
インデントはスペース4つ
例外を握りつぶさない
publicは必要なものだけにする
フォーマットはEditorConfigに従う
最低限のルールを守れる状態にしてから、必要に応じて追加していく方が定着しやすくなります。
8-2. 公式ガイドラインをベースにする
C#コーディング規約をゼロから作る必要はありません。MicrosoftのC#コード規約や.NETの命名ガイドラインをベースにすると、一般的な慣習から外れにくくなります。Microsoftのドキュメントでも、自社ドキュメントやサンプルで使う規約は、チームのニーズに合わせてそのまま使うことも変更することもできると説明されています。
公式ガイドラインをそのまま採用する必要はありませんが、「なぜこのルールにするのか」を説明しやすくなります。特に初心者が多いチームでは、一般的なC#の書き方に合わせた方が学習コストも下がります。
8-3. コードレビューで指摘基準をそろえる
コードレビューで人によって指摘内容が違うと、開発者は混乱します。
ある人はvarを推奨し、別の人は型明示を求める。ある人はコメントを増やすように言い、別の人はコメントを減らすように言う。このような状態では、規約が定着しません。
レビュー観点をそろえるために、チームで指摘基準を共有しましょう。フォーマットや命名のように自動化できるものはツールに任せ、人は設計や仕様の確認に集中するのが理想です。
8-4. サンプルコードを用意して迷いを減らす
文章だけの規約は、解釈が分かれることがあります。サンプルコードを用意すると、迷いを減らせます。
たとえば、次のようなサンプルがあると実装時に参考にしやすくなります。
C#public class OrderService
{
private readonly IOrderRepository _orderRepository;
public OrderService(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public async Task<Order?> GetOrderAsync(int orderId)
{
if (orderId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(orderId));
}
return await _orderRepository.FindByIdAsync(orderId);
}
}
このサンプルには、クラス名、フィールド名、コンストラクタ、非同期メソッド、例外処理、null許容の考え方が含まれています。実際のプロジェクトに近いサンプルを用意すると、規約を実装に落とし込みやすくなります。
8-5. 定期的に規約を見直す
C#や.NETは継続的に進化しています。新しい言語機能や開発ツールが追加されることで、以前のルールが今の書き方に合わなくなることもあります。
たとえば、Nullable Reference Types、record、requiredプロパティ、file-scoped namespaceなど、近年のC#ではコードの書き方に影響する機能が増えています。規約を一度作って終わりにするのではなく、定期的に見直しましょう。
見直しの際は、次の観点で確認すると効果的です。
実際に守られているか
ルールが細かすぎないか
新しいC#機能に対応できているか
ツールで自動チェックできるか
レビュー時の負担を減らせているか
規約はチームを縛るためのものではなく、開発を進めやすくするためのものです。現場に合う形で改善し続けましょう。
まとめ
C#コーディング規約は、読みやすく保守しやすいコードを書くための基本です。初心者のうちは文法を覚えることに集中しがちですが、実務では命名、インデント、コメント、例外処理、null対策、責務の分け方なども重要になります。
クラス名やメソッド名はPascalCase、ローカル変数や引数はcamelCaseを基本にし、bool型はisActiveやhasPermissionのように意味が伝わる名前にしましょう。インデントや改行を整え、1行に処理を詰め込みすぎず、ネストを浅くすることで、コードは格段に読みやすくなります。
また、保守しやすいC#コードにするには、メソッドやクラスの責務を明確にし、重複コードを避け、例外処理やnull対策を適切に行うことが大切です。非同期処理ではAsyncサフィックスやasync/awaitの使い方にも注意しましょう。
規約をチームに定着させるには、EditorConfig、StyleCop Analyzers、Roslyn Analyzer、CIなどのツールを活用し、自動化できる部分は機械に任せるのが効果的です。そのうえで、人間は設計やロジックの妥当性をレビューすることに集中できます。
C#コーディング規約は、最初から完璧に作る必要はありません。まずは基本的な命名規則と読みやすい書き方から始め、プロジェクトやチームの状況に合わせて少しずつ改善していきましょう。

