C#コーディング規約完全ガイド|命名規則・書き方・チーム開発で迷わない実践ルール
はじめに
C#で開発を続けていると、「クラス名はどう付けるべきか」「privateフィールドにアンダースコアを付けるべきか」「varは使ってよいのか」「コメントはどこまで書くべきか」といった判断に何度も出会います。
個人開発であれば好みで済むこともありますが、チーム開発では書き方のばらつきがレビュー負荷や保守コストにつながります。そこで必要になるのが、C#コーディング規約です。
C#規約は、単に見た目をそろえるためのルールではありません。コードを読む人が迷わず理解でき、変更時の影響を把握しやすくし、チーム全体で安定した品質を保つための共通ルールです。
この記事では、C#の命名規則、書き方、コメント、例外処理、async/await、ツールによる自動化、実際に使える規約サンプルまで、現場で迷いやすいポイントを実践的に整理します。
1. C#コーディング規約とは?チーム開発で必要になる理由
C#コーディング規約とは、C#でコードを書くときの命名、書式、コメント、ファイル構成、実装方針などをチーム内で統一するためのルールです。
たとえば、同じ意味の変数があるのに、ある人は userList、別の人は users、また別の人は lstUser と書いていると、読む側は毎回意図を確認しなければなりません。規約があれば、「この種類の名前はこう書く」という前提を共有できます。
C#は言語機能が豊富で、同じ処理でも複数の書き方ができます。だからこそ、プロジェクトごとに「どの書き方を標準にするか」を決めておくことが重要です。
1-1. コーディング規約の目的は「読みやすさ」と「保守しやすさ」をそろえること
コーディング規約の最大の目的は、コードの読みやすさと保守しやすさをチーム全体でそろえることです。
読みやすいコードとは、単に短いコードではありません。名前から役割が分かり、処理の流れが自然で、不要なばらつきが少ないコードです。保守しやすいコードとは、修正箇所を見つけやすく、変更しても影響範囲を把握しやすいコードです。
たとえば、次のように命名が統一されていないコードは、処理内容よりも名前の違いに意識を取られます。
C#var usr = GetUser();
var userInfo = GetUserInfo();
var user_data = LoadUserData();
一方、役割に応じて命名が整理されていれば、コードの意図を追いやすくなります。
C#var user = GetUser();
var userProfile = GetUserProfile();
var userSettings = LoadUserSettings();
C#規約は、開発者の個性を消すものではなく、チームで読みやすいコードを書くための土台です。
1-2. C#で規約が重要になる場面:レビュー・保守・引き継ぎ・共同開発
C#コーディング規約が特に効果を発揮するのは、次のような場面です。
| 場面 | 規約がない場合の問題 | 規約がある場合の効果 |
|---|---|---|
| コードレビュー | 書き方の好みに関する指摘が増える | 本質的な設計や不具合に集中できる |
| 保守 | ファイルごとに書き方が違い読みにくい | 既存コードの理解が早くなる |
| 引き継ぎ | 暗黙ルールが分からない | 新メンバーが参加しやすい |
| 共同開発 | 命名や構成が人によって変わる | チーム全体で一貫性を保てる |
| 不具合調査 | 例外処理やログ出力がばらつく | 調査しやすい構造になる |
特に業務システムや長期運用されるプロダクトでは、コードを書く時間よりも読む時間のほうが長くなります。そのため、将来の保守担当者が迷わない書き方を決めておくことが重要です。
1-3. コーディング規約とコーディングスタイル・設計方針の違い
コーディング規約、コーディングスタイル、設計方針は似ていますが、対象範囲が少し異なります。
コーディング規約は、命名規則、インデント、コメント、ファイル構成など、コードを書くときの具体的なルールです。
コーディングスタイルは、より見た目や書き味に近いルールです。たとえば、波括弧の位置、空行の入れ方、1行の長さ、var の使用方針などが含まれます。
設計方針は、アーキテクチャや責務分離、依存関係、レイヤー構成など、より大きな構造に関するルールです。
たとえば、以下のように分けると整理しやすくなります。
| 種類 | 例 |
|---|---|
| コーディング規約 | クラス名はPascalCase、privateフィールドは _camelCase |
| コーディングスタイル | 波括弧は改行して書く、インデントはスペース4つ |
| 設計方針 | Controllerに業務ロジックを書かない、RepositoryはDBアクセスに限定する |
規約を作るときは、すべてを1つの文書に詰め込むより、コードの書き方と設計方針を分けて管理すると読みやすくなります。
1-4. Microsoft公式のC#規約はどこまで採用すべきか
C#の規約を作るときは、Microsoft公式の命名ガイドラインやC#コーディング規約をベースにするのが基本です。C#の標準ライブラリや一般的なサンプルコードと書き方が近くなるため、学習コストを下げられます。
たとえば、C#ではクラス名、メソッド名、プロパティ名にPascalCaseを使うのが一般的です。
C#public class CustomerService
{
public Customer GetCustomer(int customerId)
{
// ...
}
}
ただし、Microsoft公式の規約をすべてそのまま採用すればよいわけではありません。プロジェクトの種類やチームの文化によって、使いやすいルールは変わります。
たとえば、privateフィールドにアンダースコアを付けるかどうかは、チームによって方針が分かれます。Unity開発ではシリアライズ対象フィールドの扱いが独特になることもあります。ASP.NET Coreでは、依存性注入や非同期処理に関する規約も重要になります。
基本は公式規約に寄せつつ、現場で迷いやすい部分を補足する形が実践的です。
2. C#コーディング規約を作る前に押さえる基本方針
C#コーディング規約は、細かく書けばよいものではありません。大切なのは、開発者が迷いやすい部分を明確にし、チームで守り続けられるルールにすることです。
厳しすぎる規約は開発スピードを落とし、曖昧すぎる規約はレビュー指摘のばらつきを生みます。規約は「理想のコード集」ではなく、「チームが実際に運用できる共通ルール」として作る必要があります。
2-1. 規約は細かくしすぎず「迷いやすい部分」を優先する
最初からすべての書き方を細かく決めようとすると、規約が長くなりすぎて読まれなくなります。
優先すべきなのは、次のような迷いやすい部分です。
| 優先度 | 決めるべき項目 |
|---|---|
| 高 | 命名規則、インデント、波括弧、nullの扱い、例外処理 |
| 中 | コメント方針、メンバーの並び順、var の使用方針 |
| 低 | 空行の細かな位置、式の好み、個人差の小さい書き方 |
たとえば、次のようなルールは実用性が高いです。
・クラス名、メソッド名、プロパティ名はPascalCaseにする
・ローカル変数と引数はcamelCaseにする
・privateフィールドは_camelCaseにする
・インデントはスペース4つにする
・例外を握りつぶさない
一方で、「空行は必ず何行まで」「LINQは何行以内なら使う」など、細かすぎるルールは現場で判断しづらくなることがあります。
2-2. プロジェクト全体で統一すべきルールと個人に任せるルール
C#規約では、すべてを統一する必要はありません。プロジェクト全体で必ずそろえるべきルールと、個人の判断に任せても大きな問題がないルールを分けることが重要です。
プロジェクト全体で統一すべきなのは、コードの読み方に直接影響する部分です。
・命名規則
・インデント
・改行と波括弧
・nullの扱い
・例外処理
・ログ出力
・ファイル構成
・公開APIのコメント
一方、次のような部分は、必要以上に縛らなくてもよい場合があります。
・メソッド内の一時変数の分け方
・単純なLINQとforeachの選択
・短い式の改行位置
・説明不要な箇所へのコメント有無
大切なのは、「他の人が読んだときに困るかどうか」です。困るものは規約化し、困らないものは開発者の判断に任せると、運用しやすい規約になります。
2-3. 既存コードがある場合の規約導入の考え方
既存コードがあるプロジェクトにC#コーディング規約を導入する場合、すべてを一度に直そうとしないことが重要です。
大規模な一括修正を行うと、差分が膨大になり、機能変更との区別がつきにくくなります。また、不要なコンフリクトが増え、開発効率が下がることもあります。
現実的には、次のような段階的な導入がおすすめです。
1. 新規コードから規約を適用する
2. 修正対象の周辺コードだけ整える
3. 自動フォーマットできる範囲を先に統一する
4. 命名変更など影響が大きい修正は別タスクにする
5. CIでチェックする項目を段階的に増やす
特に、命名変更やクラス分割は影響範囲が広くなるため、機能修正と混ぜないほうが安全です。
2-4. 新人・初心者にも伝わるC#規約にするポイント
C#規約は、経験者だけが理解できる書き方ではなく、新人や初心者にも伝わる内容にする必要があります。
たとえば、「適切に命名する」と書くだけでは曖昧です。良い例と悪い例を並べると、判断しやすくなります。
C#// 悪い例
var d = DateTime.Now;
var flg = true;
var list = GetCustomers();
// 良い例
var currentDate = DateTime.Now;
var isEnabled = true;
var customers = GetCustomers();
また、ルールの理由も簡単に添えると納得感が高まります。
bool型の変数は、true/falseの意味が読み取れるように is、has、can、should などで始める。
理由:if文で読んだときに条件の意味が分かりやすくなるため。
規約は「守れ」ではなく、「なぜその書き方にするのか」が伝わる形にすると定着しやすくなります。
3. C#の命名規則:クラス・メソッド・変数の書き方
C#コーディング規約の中でも、命名規則は特に重要です。名前はコードの説明そのものだからです。
よい名前が付いていれば、コメントが少なくても処理の意図が分かります。逆に名前が曖昧だと、どれだけコメントを書いてもコード全体が読みにくくなります。
C#では、PascalCase、camelCase、_camelCaseを使い分けるのが一般的です。
3-1. PascalCase・camelCase・_camelCaseの使い分け
C#の命名では、主に次の3種類を使います。
| 記法 | 例 | 主な用途 |
|---|---|---|
| PascalCase | CustomerService | クラス、メソッド、プロパティ、イベント |
| camelCase | customerName | ローカル変数、引数 |
| _camelCase | _customerRepository | privateフィールド |
PascalCaseは、単語の先頭をすべて大文字にします。
C#public class OrderService
{
public Order GetOrder(int orderId)
{
// ...
}
}
camelCaseは、先頭の単語だけ小文字にします。
C#public void UpdateCustomer(string customerName, int customerAge)
{
var normalizedName = customerName.Trim();
}
_camelCaseは、privateフィールドでよく使われます。
C#public class CustomerService
{
private readonly ICustomerRepository _customerRepository;
public CustomerService(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
}
チームで重要なのは、どの記法を使うかを明確にして、ファイルごとに混在させないことです。
3-2. クラス名・構造体名・インターフェイス名の命名規則
クラス名と構造体名はPascalCaseで書き、役割が分かる名詞または名詞句にします。
C#public class CustomerService
{
}
public class OrderRepository
{
}
public struct Money
{
}
クラス名には、何を表すクラスなのかが分かる名前を付けます。Data、Info、Manager のような汎用的な名前は、意味が曖昧になりやすいため注意が必要です。
C#// 避けたい例
public class UserData
{
}
public class SystemManager
{
}
// 分かりやすい例
public class UserProfile
{
}
public class NotificationScheduler
{
}
インターフェイス名は、C#では先頭に I を付けるのが一般的です。
C#public interface IUserRepository
{
User FindById(int userId);
}
public interface IEmailSender
{
Task SendAsync(EmailMessage message);
}
インターフェイス名も、実装方法ではなく役割で命名します。ISqlUserRepository のように技術要素を入れるかどうかは、抽象化の目的に応じて判断します。
3-3. メソッド名・プロパティ名・イベント名の命名規則
メソッド名はPascalCaseで書き、動詞または動詞句にします。
C#public Customer GetCustomer(int customerId)
{
// ...
}
public void UpdateStatus(OrderStatus status)
{
// ...
}
public bool CanCancel(Order order)
{
// ...
}
取得するメソッドには Get、作成には Create、更新には Update、削除には Delete など、一般的な動詞を使うと意図が伝わりやすくなります。
プロパティ名はPascalCaseで書き、名詞または形容詞句にします。
C#public string CustomerName { get; set; }
public bool IsActive { get; private set; }
public DateTime CreatedAt { get; init; }
イベント名もPascalCaseで書き、発生した事象が分かる名前にします。
C#public event EventHandler<OrderCreatedEventArgs>? OrderCreated;
public event EventHandler? Completed;
イベントハンドラのメソッド名は、On を付ける書き方がよく使われます。
C#protected virtual void OnOrderCreated(OrderCreatedEventArgs e)
{
OrderCreated?.Invoke(this, e);
}
3-4. ローカル変数・引数・privateフィールドの命名規則
ローカル変数と引数はcamelCaseで書きます。
C#public decimal CalculateTotalPrice(IEnumerable<OrderItem> orderItems)
{
var totalPrice = orderItems.Sum(item => item.Price * item.Quantity);
return totalPrice;
}
短すぎる名前は避け、役割が分かる名前にします。
C#// 避けたい例
var x = GetTotalPrice();
var tmp = GetCustomer();
var list = GetOrders();
// 分かりやすい例
var totalPrice = GetTotalPrice();
var customer = GetCustomer();
var orders = GetOrders();
ただし、短いスコープで使うループ変数やLINQのラムダ引数では、i、x、item などを使っても問題ありません。
C#for (var i = 0; i < customers.Count; i++)
{
Console.WriteLine(customers[i].Name);
}
var activeUsers = users.Where(user => user.IsActive);
privateフィールドは、チームで方針を決めます。実務では _camelCase を採用するケースが多くあります。
C#private readonly ILogger<OrderService> _logger;
private readonly IOrderRepository _orderRepository;
アンダースコアを付けると、ローカル変数や引数とフィールドを区別しやすくなります。
3-5. 定数・enum・namespace・ファイル名の命名規則
定数はPascalCaseで書くのがC#では一般的です。
C#public const int MaxRetryCount = 3;
private const string DefaultDateFormat = "yyyy-MM-dd";
他の言語では MAX_RETRY_COUNT のような大文字スネークケースを使うこともありますが、C#ではPascalCaseに統一すると自然です。
enum名とenumの値もPascalCaseで書きます。
C#public enum OrderStatus
{
Pending,
Paid,
Shipped,
Cancelled
}
namespaceはPascalCaseで、会社名、製品名、機能名などを階層化します。
C#namespace SampleApp.Orders.Services;
ファイル名は、基本的にクラス名と一致させます。
CustomerService.cs
OrderRepository.cs
IEmailSender.cs
OrderStatus.cs
1ファイルに複数の主要クラスを入れると探しにくくなるため、原則として1ファイル1主要型にします。
3-6. 略語・省略名・日本語名を使うときの注意点
略語や省略名は、チーム全員が理解できるものに限定します。
C#// 避けたい例
var usr = GetUser();
var custNm = customer.Name;
var calcRslt = Calculate();
// 分かりやすい例
var user = GetUser();
var customerName = customer.Name;
var calculationResult = Calculate();
Id、Url、Http など一般的な略語は使っても問題ありません。ただし、表記はチームで統一します。
C#public int CustomerId { get; set; }
public string ImageUrl { get; set; } = string.Empty;
public HttpClient HttpClient { get; }
日本語名は、原則として避けるのが無難です。C#では日本語の識別子も使えますが、外部ライブラリ、検索性、チーム内の表記ゆれを考えると、英語名に統一したほうが保守しやすくなります。
ただし、業務ドメイン上どうしても日本語の概念を残したほうが分かりやすい場合は、用語集を作り、英訳を統一します。
顧客 → Customer
請求 → Billing
入金 → Payment
出荷 → Shipment
3-7. asyncメソッド・bool変数・コレクション名の命名ルール
非同期メソッドは、メソッド名の末尾に Async を付けます。
C#public Task<Customer> GetCustomerAsync(int customerId)
{
// ...
}
bool変数やboolプロパティは、true/falseの意味が分かる名前にします。
C#public bool IsActive { get; set; }
public bool HasPermission { get; set; }
public bool CanCancel { get; set; }
public bool ShouldRetry { get; set; }
次のような名前は、条件式で読みにくくなります。
C#// 避けたい例
if (flag)
{
}
if (check)
{
}
コレクションは、複数形または内容が分かる名前にします。
C#var customers = GetCustomers();
var activeOrders = GetActiveOrders();
var userIds = users.Select(user => user.Id).ToList();
list、array、data のような型や抽象的な名前だけでは、何の集合なのかが分かりません。
4. C#の書き方規約:インデント・括弧・改行・コメント
C#の書き方規約では、インデント、波括弧、改行、空行、コメントなどを統一します。これらは処理内容そのものには影響しませんが、コードの読みやすさに大きく関わります。
書式に関する議論は好みの対立になりやすいため、チームで決めたらツールで自動適用するのが理想です。
4-1. インデントはスペースかタブか:チームで統一すべき設定
C#では、インデントにスペース4つを使うケースが一般的です。
C#public class CustomerService
{
public Customer GetCustomer(int customerId)
{
return new Customer();
}
}
重要なのは、スペースかタブかの正解を議論し続けることではなく、プロジェクト内で統一することです。開発者ごとに設定が違うと、差分に不要な空白変更が混ざります。
EditorConfigを使えば、リポジトリ単位でインデント設定を共有できます。
INI[*.cs]
indent_style = space
indent_size = 4
このようにツールで統一できるルールは、レビューで人が指摘するよりも自動化したほうが効率的です。
4-2. 波括弧の位置と改行ルール
C#では、波括弧を次の行に置くスタイルが広く使われます。
C#public void UpdateStatus(Order order)
{
if (order.IsPaid)
{
order.Status = OrderStatus.Paid;
}
}
チーム規約としては、次のように決めておくと迷いません。
・クラス、メソッド、if、for、foreach、whileの波括弧は改行する
・1行のif文でも波括弧を省略しない
・else、catch、finallyは前のブロックの後に続けて書く
波括弧を省略すると、後から処理を追加したときにミスが起きやすくなります。
C#// 避けたい例
if (isValid)
Save();
// 推奨
if (isValid)
{
Save();
}
多少行数が増えても、保守性を優先するなら波括弧を常に書くルールがおすすめです。
4-3. 1行の長さ・空行・コードブロックの分け方
1行が長すぎるコードは読みづらくなります。厳密な文字数はチームで決めればよいですが、120文字前後を目安にすると扱いやすいです。
C#var activeCustomers = customers
.Where(customer => customer.IsActive)
.OrderBy(customer => customer.Name)
.ToList();
空行は、処理のまとまりを分けるために使います。
C#public async Task<Order> CreateOrderAsync(CreateOrderRequest request)
{
var customer = await _customerRepository.FindAsync(request.CustomerId);
if (customer is null)
{
throw new CustomerNotFoundException(request.CustomerId);
}
var order = Order.Create(customer, request.Items);
await _orderRepository.SaveAsync(order);
return order;
}
ただし、空行を入れすぎると逆に流れが追いづらくなります。意味のある単位で区切ることが大切です。
4-4. usingディレクティブとnamespaceの書き方
using ディレクティブはファイルの先頭にまとめます。不要な using は削除します。
C#using SampleApp.Orders.Models;
using SampleApp.Orders.Repositories;
namespace SampleApp.Orders.Services;
public class OrderService
{
}
新しいC#では、ファイルスコープnamespaceを使うことでインデントを浅くできます。
C#namespace SampleApp.Customers.Services;
public class CustomerService
{
}
ただし、既存コードがブロックスコープnamespaceで統一されている場合は、プロジェクト内で混在しないようにします。
C#namespace SampleApp.Customers.Services
{
public class CustomerService
{
}
}
規約としては、次のように決めておくとよいです。
・新規ファイルではファイルスコープnamespaceを使用する
・既存ファイルは周辺コードのスタイルに合わせる
・不要なusingは削除する
4-5. コメントを書くべき場所・書かないほうがよい場所
コメントは、多ければよいわけではありません。コードを読めば分かる内容をコメントにすると、変更時にコメントだけ古くなる危険があります。
C#// 悪い例:コードを読めば分かる
// customerIdに1を足す
customerId++;
コメントを書くべきなのは、「なぜそうしているのか」を説明する場面です。
C#// 外部APIの仕様上、同じリクエストを短時間に再送すると重複登録されるため待機する
await Task.Delay(TimeSpan.FromSeconds(2));
おすすめの方針は次のとおりです。
・処理内容ではなく理由を書く
・業務上の制約を書く
・外部仕様や一時的な回避策を書く
・TODOには期限や担当を添える
・古いコメントはコード修正時に更新する
コメントに頼る前に、まず名前やメソッド分割で意図を表現できないかを考えます。
4-6. XMLドキュメントコメントの使いどころ
XMLドキュメントコメントは、公開API、共通ライブラリ、外部から利用されるクラスやメソッドに付けると効果的です。
C#/// <summary>
/// 指定された顧客IDに紐づく注文一覧を取得します。
/// </summary>
/// <param name="customerId">顧客ID。</param>
/// <returns>注文一覧。</returns>
public Task<IReadOnlyList<Order>> GetOrdersAsync(int customerId)
{
// ...
}
一方、privateメソッドすべてにXMLコメントを付ける必要はありません。内部実装にコメントが多すぎると、保守時の更新漏れが増えます。
規約としては、次のような基準が実用的です。
・publicなクラス、メソッド、プロパティには必要に応じてXMLコメントを書く
・共通ライブラリや外部公開APIではXMLコメントを必須にする
・privateメソッドは名前で意図が分かるようにし、原則XMLコメントは不要
4-7. ファイル構成とクラス内メンバーの並び順
ファイル構成は、探しやすさに直結します。基本は1ファイル1主要クラスにします。
Orders/
Models/
Order.cs
OrderItem.cs
Services/
OrderService.cs
Repositories/
IOrderRepository.cs
OrderRepository.cs
クラス内のメンバー順も統一すると読みやすくなります。
1. 定数
2. privateフィールド
3. コンストラクタ
4. publicプロパティ
5. publicメソッド
6. privateメソッド
例は次のとおりです。
C#public class OrderService
{
private const int MaxRetryCount = 3;
private readonly IOrderRepository _orderRepository;
public OrderService(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public Task<Order> GetOrderAsync(int orderId)
{
return _orderRepository.FindAsync(orderId);
}
private static bool IsValidOrderId(int orderId)
{
return orderId > 0;
}
}
並び順は絶対ではありませんが、チームで標準を決めておくと、コードレビューで迷いにくくなります。
5. C#らしい実装ルール:可読性を高める実践規約
C#規約では、見た目だけでなく、C#らしい実装方針も決めておくと効果的です。特に、var、プロパティ、null、例外処理、LINQ、async/awaitは、チーム内で書き方が分かれやすいポイントです。
5-1. varを使うべき場面・明示的な型を書くべき場面
var は便利ですが、使いすぎると型が分かりにくくなることがあります。規約では、型が右辺から明確に分かる場合は var を許可し、分かりにくい場合は明示的な型を書く、という方針が実用的です。
C#// varを使ってよい例
var customer = new Customer();
var orders = new List<Order>();
var totalPrice = orderItems.Sum(item => item.Price);
右辺から型が分かりにくい場合は、明示的に型を書くと読みやすくなります。
C#// 明示的な型が分かりやすい例
IEnumerable<Customer> customers = GetCustomers();
Stream stream = file.OpenRead();
ただし、チームによっては「常にvar」「組み込み型以外はvar」などの方針もあります。重要なのは、プロジェクト内で一貫性を保つことです。
5-2. プロパティ・フィールド・コンストラクタの書き方
C#では、外部に公開する状態はフィールドではなくプロパティで表現します。
C#public class Customer
{
public int Id { get; init; }
public string Name { get; private set; }
public Customer(int id, string name)
{
Id = id;
Name = name;
}
}
外部から変更されたくない値は、private set や init を使って制御します。
C#public DateTime CreatedAt { get; init; }
public DateTime? UpdatedAt { get; private set; }
依存性注入で受け取るサービスは、コンストラクタで受け取り、readonly フィールドに保持します。
C#public class OrderService
{
private readonly IOrderRepository _orderRepository;
private readonly ILogger<OrderService> _logger;
public OrderService(
IOrderRepository orderRepository,
ILogger<OrderService> logger)
{
_orderRepository = orderRepository;
_logger = logger;
}
}
コンストラクタでは、必要に応じてnullチェックを行います。
C#_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
5-3. nullの扱いとNullable Reference Typesの規約
C#では、nullの扱いを曖昧にすると実行時エラーの原因になります。Nullable Reference Typesを有効にして、nullになり得る値となり得ない値を型で表現するのがおすすめです。
C#public class Customer
{
public string Name { get; set; } = string.Empty;
public string? Email { get; set; }
}
string はnullを許容しない文字列、string? はnullの可能性がある文字列として扱います。
nullチェックは、早めに行うと処理の本筋が読みやすくなります。
C#public Customer GetCustomer(int customerId)
{
var customer = _customerRepository.Find(customerId);
if (customer is null)
{
throw new CustomerNotFoundException(customerId);
}
return customer;
}
規約としては、次のような方針が有効です。
・Nullable Reference Typesを有効にする
・nullを許容する場合は ? を付ける
・nullを返すメソッドは名前やコメントで意図を明確にする
・不要な null! は使わない
・引数のnullチェック方針を統一する
5-4. 例外処理の書き方とcatchのルール
例外処理では、例外を握りつぶさないことが重要です。
C#// 避けたい例
try
{
Save(order);
}
catch
{
}
何もせずにcatchすると、不具合の原因が分からなくなります。catchする場合は、ログを出す、適切な例外に変換する、ユーザーに分かる形で通知するなど、目的を明確にします。
C#try
{
await _orderRepository.SaveAsync(order);
}
catch (DbUpdateException ex)
{
_logger.LogError(ex, "注文の保存に失敗しました。OrderId: {OrderId}", order.Id);
throw new OrderSaveException(order.Id, ex);
}
規約としては、次のように決めるとよいです。
・catch対象の例外型を具体的に書く
・例外を握りつぶさない
・ログには調査に必要な情報を含める
・例外を再throwするときは throw; を使う
・業務例外とシステム例外を区別する
再throwで throw ex; を使うとスタックトレースが分かりにくくなるため、通常は throw; を使います。
C#catch (Exception)
{
throw;
}
5-5. LINQを使う場面・通常のループを使う場面
LINQはC#らしい書き方ですが、複雑にしすぎると読みにくくなります。
シンプルな抽出、変換、集計にはLINQが向いています。
C#var activeCustomers = customers
.Where(customer => customer.IsActive)
.OrderBy(customer => customer.Name)
.ToList();
一方、条件分岐や副作用が多い処理は、通常のループのほうが読みやすい場合があります。
C#foreach (var order in orders)
{
if (!order.CanShip())
{
_logger.LogWarning("出荷できない注文です。OrderId: {OrderId}", order.Id);
continue;
}
order.Ship();
}
規約としては、次のような基準が実用的です。
・単純な抽出、変換、集計にはLINQを使う
・副作用がある処理はforeachを使う
・LINQを何段もネストしない
・読みづらいLINQは中間変数やメソッドに分ける
LINQは短く書くためではなく、意図を分かりやすく表現するために使います。
5-6. async/awaitの書き方とConfigureAwaitの扱い
非同期処理では、メソッド名に Async を付け、戻り値は基本的に Task または Task<T> にします。
C#public async Task<Customer> GetCustomerAsync(int customerId)
{
var customer = await _customerRepository.FindAsync(customerId);
if (customer is null)
{
throw new CustomerNotFoundException(customerId);
}
return customer;
}
async void は、イベントハンドラなど一部の例外を除いて避けます。
C#// 避けたい例
public async void SaveAsync()
{
await _repository.SaveAsync();
}
// 推奨
public async Task SaveAsync()
{
await _repository.SaveAsync();
}
ConfigureAwait(false) の扱いは、アプリケーションの種類によって方針が変わります。ライブラリ開発では使用を検討し、ASP.NET Coreなどではチームの方針に合わせて統一します。
規約としては、次のように決めておくと迷いにくくなります。
・非同期メソッド名はAsyncで終える
・async voidはイベントハンドラ以外で使わない
・Task.ResultやWait()で同期的に待たない
・ConfigureAwaitの使用方針をプロジェクトで統一する
5-7. マジックナンバー・定数・設定値の管理ルール
意味の分からない数値や文字列をコードに直接書くと、後から変更しにくくなります。
C#// 避けたい例
if (retryCount > 3)
{
throw new InvalidOperationException();
}
意味のある名前を付けて定数化します。
C#private const int MaxRetryCount = 3;
if (retryCount > MaxRetryCount)
{
throw new InvalidOperationException();
}
ただし、すべての数値を定数化する必要はありません。0、1、空文字など、文脈上明らかな値はそのままでも問題ない場合があります。
環境ごとに変わる値は、定数ではなく設定ファイルや環境変数で管理します。
JSON{
"Retry": {
"MaxRetryCount": 3,
"IntervalSeconds": 5
}
}
規約としては、次のように整理できます。
・業務的な意味を持つ数値や文字列は定数化する
・環境ごとに変わる値は設定値にする
・同じリテラルが複数箇所に出る場合は共通化を検討する
・名前は値ではなく意味を表す
6. チーム開発で迷わないC#規約の運用方法
C#コーディング規約は、作って終わりではありません。運用されなければ意味がありません。
チームで使われる規約にするには、レビュー、自動チェック、ドキュメント更新、新メンバーへの共有まで含めて考える必要があります。
6-1. コードレビューで確認する規約項目
コードレビューでは、すべてを人が確認しようとすると負担が大きくなります。ツールで検出できるものと、人が見るべきものを分けます。
人が確認すべき項目は、主に次のような内容です。
・名前から役割が分かるか
・責務が大きすぎないか
・例外処理が適切か
・nullの扱いが安全か
・コメントが必要な理由を説明しているか
・テストしやすい構造になっているか
一方、インデントや空白、usingの並び順などは、自動フォーマットに任せるべきです。
レビューでは、「規約違反を探す」よりも、「保守しやすいコードになっているか」を確認する意識が大切です。
6-2. Pull Requestで指摘が増えない規約の決め方
Pull Requestで細かい指摘が増えると、開発者の負担が大きくなります。規約で避けるべきなのは、人によって判断が変わる曖昧なルールです。
たとえば、次のようなルールは指摘が属人化しやすくなります。
・分かりやすい名前にする
・適度にコメントを書く
・複雑な処理は分割する
これを、具体的な基準に変えます。
・bool変数は is、has、can、should のいずれかで始める
・コメントは処理内容ではなく理由を書く
・1メソッドが長くなりすぎる場合は責務分割を検討する
すべてを数値化する必要はありませんが、判断の目安があるとレビューしやすくなります。
6-3. 規約違反を個人攻撃にしないレビュー文化
コーディング規約の指摘は、個人攻撃にならないように注意が必要です。
悪い指摘の例です。
この書き方は読みにくいです。
なぜ規約を守っていないのですか?
よい指摘の例です。
このプロジェクトではprivateフィールドを_camelCaseに統一しているため、_customerRepositoryに変更してください。
規約に基づいた指摘であれば、個人の好みではなくチームの合意として伝えられます。
また、規約違反が頻発する場合は、個人の問題ではなく、規約が分かりにくい、ツール設定が不足している、共有が足りないと考えるべきです。
6-4. 既存メンバーと新規メンバーで認識をそろえる方法
新規メンバーが参加したときに、暗黙のルールが多いとキャッチアップに時間がかかります。
次のような仕組みを用意しておくと、認識をそろえやすくなります。
・READMEに規約へのリンクを置く
・代表的なコード例を用意する
・EditorConfigをリポジトリに含める
・Pull Requestテンプレートに確認項目を書く
・オンボーディング時に規約を説明する
特に、良いコード例があると理解が早くなります。規約文書だけでなく、「このプロジェクトではこの書き方が標準」というサンプルコードを用意しておくと効果的です。
6-5. 規約をドキュメント化する場所と更新ルール
C#規約は、チーム全員が見つけやすい場所に置きます。
よく使われる場所は次のとおりです。
・リポジトリ直下の README.md
・docs/coding-standards.md
・チームWiki
・NotionやConfluence
おすすめは、リポジトリ内に規約文書を置く方法です。コードと同じPull Requestで変更できるため、規約の更新履歴を追いやすくなります。
docs/
coding-standards.md
.editorconfig
Directory.Build.props
更新ルールも決めておきます。
・規約変更はPull Requestで提案する
・変更理由を書く
・既存コードへの適用範囲を明確にする
・ツール設定も同時に更新する
規約は固定されたものではなく、チームの成長に合わせて見直すものです。
6-6. Unity・ASP.NET Core・業務システムで変わる規約の考え方
C#といっても、開発対象によって重視する規約は変わります。
Unity開発では、MonoBehaviour、SerializeField、Updateメソッド、パフォーマンス、Inspector表示などを考慮する必要があります。
C#[SerializeField]
private float _moveSpeed = 5.0f;
ASP.NET Coreでは、Controller、Service、Repository、DTO、非同期処理、依存性注入、ログ出力などの規約が重要です。
C#public async Task<IActionResult> GetCustomerAsync(int customerId)
{
var customer = await _customerService.GetCustomerAsync(customerId);
return Ok(customer);
}
業務システムでは、ドメイン用語、例外処理、トランザクション、監査ログ、設定値管理が重要になります。
つまり、C#規約はすべてのプロジェクトで同じにするのではなく、開発対象に応じて必要な項目を追加することが大切です。
7. C#コーディング規約を自動化するツール
C#規約をチームに定着させるには、自動化が欠かせません。人が手作業でインデントや空白を確認していると、レビューが疲弊します。
書式や単純なルールはツールに任せ、人は設計や可読性の判断に集中するのが理想です。
7-1. EditorConfigでC#の書式ルールを統一する
EditorConfigは、インデント、改行、文字コード、C#の書式ルールなどをリポジトリ単位で共有できる設定ファイルです。
リポジトリ直下に .editorconfig を置くことで、Visual Studio、Rider、VS Codeなどで同じ書式を適用しやすくなります。
INIroot = true
[*.cs]
indent_style = space
indent_size = 4
charset = utf-8
end_of_line = crlf
insert_final_newline = true
C#固有のルールも設定できます。
INI[*.cs]
dotnet_sort_system_directives_first = true
csharp_new_line_before_open_brace = all
csharp_prefer_braces = true:suggestion
規約文書に書いた内容と .editorconfig の内容がずれないように管理することが重要です。
7-2. Visual Studio・Rider・VS Codeで規約を適用する方法
主要なC#開発環境では、EditorConfigやフォーマッタを使って規約を適用できます。
Visual Studioでは、保存時やフォーマット実行時にEditorConfigの設定を反映できます。Riderでもコードスタイル設定やEditorConfigに対応しています。VS Codeでは、C#拡張機能やフォーマット設定を組み合わせて使います。
チームでは、開発環境ごとの設定差を減らすため、次のように決めておくとよいです。
・リポジトリの.editorconfigを正とする
・IDE固有の個人設定よりプロジェクト設定を優先する
・保存時フォーマットの使用を推奨する
・PR前にdotnet formatを実行する
IDEに依存しすぎず、リポジトリ側に設定を置くことで、参加メンバーの環境差を減らせます。
7-3. dotnet formatでフォーマットを自動化する
dotnet format を使うと、.NETプロジェクトのフォーマットや一部のコードスタイル修正をコマンドで実行できます。
Bashdotnet format
CIでチェックする場合は、変更が必要なファイルがあると失敗させることもできます。
Bashdotnet format --verify-no-changes
開発者が手元で実行するだけでなく、Pull Request時にCIでチェックすると、規約違反の混入を防ぎやすくなります。
規約としては、次のように決めると運用しやすいです。
・PR作成前にdotnet formatを実行する
・CIでフォーマット差分を検出する
・自動修正できる指摘はレビューで扱わない
7-4. StyleCop・Roslyn Analyzerで規約違反を検出する
StyleCop AnalyzersやRoslyn Analyzerを使うと、命名、コメント、メンバー順、コード品質などのルールを検出できます。
たとえば、次のような項目をチェックできます。
・命名規則に違反していないか
・不要なusingがないか
・XMLコメントが不足していないか
・未使用の変数がないか
・推奨されない書き方をしていないか
Analyzerは強力ですが、最初からすべてをエラーにすると開発が進みにくくなります。導入時は、重要なルールだけを警告またはエラーにし、段階的に増やすのがおすすめです。
XML<PropertyGroup>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
必要に応じて、特定の警告だけをエラー扱いにします。
7-5. CI/CDに規約チェックを組み込む方法
CI/CDに規約チェックを組み込むと、レビュー前に機械的な問題を検出できます。
一般的な流れは次のとおりです。
1. dotnet restore
2. dotnet build
3. dotnet test
4. dotnet format --verify-no-changes
5. Analyzerの警告チェック
GitHub Actionsの例です。
YAMLname: .NET
on:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- run: dotnet restore
- run: dotnet build --no-restore
- run: dotnet test --no-build
- run: dotnet format --verify-no-changes
CIでチェックすることで、「手元では気づかなかった規約違反」をPull Request時に発見できます。
7-6. 手作業レビューと自動チェックの役割分担
規約運用では、手作業レビューと自動チェックの役割分担が重要です。
| 項目 | 自動チェック | 人のレビュー |
|---|---|---|
| インデント | 得意 | 不要 |
| using整理 | 得意 | 不要 |
| 命名規則 | 一部可能 | 意味の妥当性は人が判断 |
| コメント | 形式は可能 | 内容は人が判断 |
| 設計 | 不得意 | 必要 |
| 例外処理 | 一部可能 | 文脈判断が必要 |
自動化できる部分は積極的に自動化し、人は「この名前で意図が伝わるか」「責務が適切か」「将来保守しやすいか」といった判断に集中します。
8. そのまま使えるC#コーディング規約サンプル
ここでは、実際のプロジェクトにそのまま流用しやすいC#コーディング規約サンプルを紹介します。必要に応じて、プロジェクトの種類やチームの方針に合わせて変更してください。
8-1. 小規模チーム向けのシンプルなC#規約テンプレート
小規模チームでは、最初から細かい規約を作りすぎず、最低限の統一ルールから始めるのがおすすめです。
# C#コーディング規約
## 命名
・クラス名、メソッド名、プロパティ名はPascalCase
・ローカル変数、引数はcamelCase
・privateフィールドは_camelCase
・インターフェイス名はIで始める
・bool値はis、has、can、shouldなどで始める
・非同期メソッドはAsyncで終える
## 書式
・インデントはスペース4つ
・波括弧は改行して書く
・1行のif文でも波括弧を省略しない
・不要なusingは削除する
## 実装
・例外を握りつぶさない
・マジックナンバーは定数化する
・null許容の値には?を付ける
・async voidはイベントハンドラ以外で使わない
## レビュー
・自動整形できる内容はツールで確認する
・レビューでは命名、責務、例外処理、可読性を中心に確認する
この程度でも、命名や書式のばらつきは大きく減らせます。
8-2. 業務システム開発向けの実践的なC#規約テンプレート
業務システムでは、保守性、ログ、例外処理、ドメイン用語の統一が特に重要です。
# 業務システム向けC#コーディング規約
## 基本方針
・業務用語は用語集に従う
・処理の意図が名前から分かるようにする
・例外処理とログ出力を統一する
・設定値は環境ごとに変更できるようにする
## 命名
・Entity、DTO、Request、Response、Service、Repositoryの命名を統一する
・DTO名は用途が分かる名前にする
・Repositoryは永続化対象の名前を含める
・Serviceは業務処理の単位で命名する
## 例外処理
・業務エラーとシステムエラーを区別する
・catchした例外はログ出力または再throwする
・ログには調査に必要なIDを含める
・ユーザー表示用メッセージと内部ログを分ける
## データアクセス
・ControllerにSQLやDBアクセス処理を書かない
・トランザクション境界を明確にする
・Repositoryはデータアクセスに責務を限定する
## 非同期処理
・I/O処理は原則async/awaitを使う
・Task.ResultやWait()を避ける
・非同期メソッドはAsyncで終える
業務システムでは、単なる書式よりも「調査しやすいか」「変更しやすいか」が重要です。
8-3. 命名規則のサンプル一覧表
| 対象 | 規則 | 例 |
|---|---|---|
| クラス | PascalCase | CustomerService |
| 構造体 | PascalCase | Money |
| インターフェイス | I + PascalCase | ICustomerRepository |
| メソッド | PascalCase | GetCustomer |
| 非同期メソッド | PascalCase + Async | GetCustomerAsync |
| プロパティ | PascalCase | CustomerName |
| イベント | PascalCase | OrderCreated |
| ローカル変数 | camelCase | customerName |
| 引数 | camelCase | customerId |
| privateフィールド | _camelCase | _customerRepository |
| 定数 | PascalCase | MaxRetryCount |
| enum | PascalCase | OrderStatus |
| enum値 | PascalCase | Pending |
| namespace | PascalCase | SampleApp.Orders |
| ファイル名 | 型名と一致 | CustomerService.cs |
命名規則は、表にしておくと新メンバーにも共有しやすくなります。
8-4. 書式・コメント・例外処理のサンプルルール
書式ルールのサンプルです。
・インデントはスペース4つ
・波括弧は改行する
・if、for、foreach、whileでは波括弧を省略しない
・1行が長くなりすぎる場合は適切に改行する
・空行は処理のまとまりごとに入れる
コメントルールのサンプルです。
・コードを読めば分かる内容はコメントしない
・コメントには理由や制約を書く
・TODOには理由、担当、期限をできるだけ書く
・public APIには必要に応じてXMLコメントを書く
例外処理ルールのサンプルです。
・catchする例外型は具体的にする
・catchして何もしないことを禁止する
・再throwはthrow;を使う
・ログには調査に必要なIDを含める
・業務例外とシステム例外を区別する
8-5. EditorConfigのサンプル設定
以下は、C#プロジェクトで使いやすい .editorconfig のサンプルです。
INIroot = true
[*]
charset = utf-8
end_of_line = crlf
insert_final_newline = true
trim_trailing_whitespace = true
[*.cs]
indent_style = space
indent_size = 4
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = false
csharp_new_line_before_open_brace = all
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_prefer_braces = true:suggestion
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = false:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
この設定はあくまで例です。プロジェクトの方針に合わせて、var の扱いや波括弧のルールを調整してください。
8-6. プロジェクトに合わせて変更すべき項目
C#規約は、プロジェクトごとに調整が必要です。特に次の項目は、チームで話し合って決めるべきです。
・privateフィールドにアンダースコアを付けるか
・varをどこまで許可するか
・ファイルスコープnamespaceを使うか
・XMLコメントをどこまで必須にするか
・Analyzerの警告をエラー扱いにするか
・ConfigureAwait(false)を使うか
・既存コードへどこまで規約を適用するか
最初から完璧な規約を目指す必要はありません。開発中に迷った点を追加し、不要なルールは削除しながら育てることが大切です。
9. C#コーディング規約でよくある失敗と対策
C#コーディング規約は便利ですが、作り方や運用を間違えると逆効果になります。ここでは、現場でよくある失敗と対策を紹介します。
9-1. 規約が細かすぎて開発スピードが落ちる
規約が細かすぎると、開発者がコードを書くたびにルール確認に時間を取られます。
たとえば、空行の位置や改行ルールを過度に細かく決めると、本質的でない指摘が増えます。
対策は、次のとおりです。
・自動化できるルールはツールに任せる
・人が判断するルールは最小限にする
・迷いやすい項目から規約化する
・守る価値が低いルールは削除する
規約は開発を縛るためではなく、開発を楽にするためのものです。
9-2. ルールが曖昧でレビュー指摘が属人化する
「分かりやすく書く」「適切に分割する」といったルールだけでは、人によって判断が変わります。
対策として、悪い例と良い例をセットで書きます。
C#// 悪い例
var data = GetData();
// 良い例
var customers = GetCustomers();
また、レビューで何度も同じ指摘が出る場合は、規約文書に追加します。レビュー指摘を個人間のやり取りで終わらせず、チームの知識として蓄積することが大切です。
9-3. 既存コードと新規コードで書き方が混在する
既存コードに規約を導入すると、新旧の書き方が混在することがあります。
対策は、適用範囲を明確にすることです。
・新規コードは新規約に従う
・既存コードは修正時に周辺範囲だけ整える
・大規模な整形変更は機能修正と分ける
・命名変更は影響範囲を確認してから行う
一括で全コードを直すよりも、段階的に統一するほうが安全です。
9-4. ツール設定と規約ドキュメントが一致していない
規約文書には「スペース4つ」と書いてあるのに、EditorConfigではタブになっている。こうした不一致は、開発者を混乱させます。
対策は、規約文書とツール設定を同じPull Requestで更新することです。
・規約を変更したら.editorconfigも確認する
・Analyzerの設定も合わせて更新する
・CIで検出するルールと文書の内容を一致させる
ドキュメントだけではなく、実際に適用される設定を正とする意識が重要です。
9-5. Microsoft公式規約を丸写しして現場に合わない
Microsoft公式の規約は非常に参考になりますが、現場の事情を無視して丸写しすると運用しにくくなることがあります。
たとえば、外部公開ライブラリではXMLコメントを厳格に求めるべきですが、社内の小規模ツールではそこまで必要ない場合もあります。
対策は、公式規約をベースにしつつ、プロジェクトに必要なルールだけを採用することです。
・公式規約を基本方針にする
・現場で迷う部分を追加する
・不要なルールは採用しない
・定期的に見直す
C#規約は、現場で使われて初めて価値があります。
10. C#コーディング規約に関するよくある質問
ここでは、C#規約を作るときによくある疑問に答えます。
10-1. C#の命名規則はMicrosoft公式に合わせるべき?
基本的には、Microsoft公式の命名規則に合わせるのがおすすめです。C#の標準的な書き方に近くなり、他の開発者が読みやすくなるためです。
クラス名、メソッド名、プロパティ名はPascalCase、ローカル変数や引数はcamelCase、インターフェイス名は I で始める方針が一般的です。
ただし、既存プロジェクトに独自ルールがあり、すでに広く定着している場合は、一気に変える必要はありません。新規コードから段階的に寄せる方法が現実的です。
10-2. privateフィールドにアンダースコアは付けるべき?
privateフィールドにアンダースコアを付けるかどうかは、チームで統一されていればどちらでも構いません。
実務では、次のように _camelCase を使うケースが多くあります。
C#private readonly IUserRepository _userRepository;
アンダースコアを付けるメリットは、フィールドとローカル変数、引数を区別しやすいことです。
C#public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
ただし、既存コードがアンダースコアなしで統一されている場合は、無理に変更しなくても問題ありません。重要なのは混在させないことです。
10-3. varは使わないほうがいい?
var は使って問題ありません。ただし、型が分かりにくくなる場面では明示的な型を書いたほうが読みやすくなります。
C#// varで問題ない例
var customer = new Customer();
// 明示的な型が分かりやすい例
IEnumerable<Customer> customers = GetCustomers();
規約としては、「右辺から型が明確な場合はvarを使う」「型が読み取りにくい場合は明示する」と決めるとバランスがよくなります。
10-4. コメントは多いほどよい?
コメントは多ければよいわけではありません。コードを読めば分かる内容のコメントは、かえってノイズになります。
C#// 悪い例
// 顧客を取得する
var customer = GetCustomer(customerId);
コメントを書くべきなのは、コードだけでは分からない理由や制約がある場合です。
C#// 外部システムのメンテナンス時間帯は更新APIが失敗するため、登録処理をスキップする
if (maintenanceWindow.Contains(currentTime))
{
return;
}
まずは名前やメソッド分割で意図を表現し、それでも補足が必要な場合にコメントを書くのが基本です。
10-5. 規約違反はどこまでレビューで指摘すべき?
自動チェックできる規約違反は、できるだけツールに任せるべきです。レビューで人が細かい空白やインデントを指摘し続けると、本質的な議論に時間を使えません。
レビューで人が見るべきなのは、次のような項目です。
・名前が意図を表しているか
・責務が適切か
・例外処理が安全か
・nullの扱いが明確か
・将来変更しやすい構造か
規約違反を見つけた場合も、個人の好みではなく、チームの規約に基づいて指摘することが大切です。
10-6. 個人開発でもC#コーディング規約は必要?
個人開発でも、最低限のC#規約はあったほうがよいです。
理由は、過去の自分のコードを後から読むことがあるためです。数か月後に見返したとき、命名や構成がばらばらだと理解に時間がかかります。
個人開発では、厳密な文書を作る必要はありません。次のような最低限のルールだけでも効果があります。
・命名規則を統一する
・インデントと改行をEditorConfigでそろえる
・例外を握りつぶさない
・マジックナンバーを避ける
・非同期メソッドはAsyncで終える
将来チーム開発に移行する可能性がある場合も、最初から一定の規約で書いておくとスムーズです。
まとめ
C#コーディング規約は、コードの見た目をそろえるためだけのルールではありません。チーム全体で読みやすく、保守しやすいコードを書くための共通基盤です。
特に重要なのは、命名規則、書式、nullの扱い、例外処理、async/await、コメント方針、ツールによる自動化です。
C#規約を作るときは、Microsoft公式の考え方をベースにしつつ、プロジェクトの種類やチームの実情に合わせて調整します。最初から完璧な規約を作る必要はありません。まずは迷いやすい部分を決め、EditorConfigやdotnet format、Analyzerで自動化しながら、少しずつ改善していくことが大切です。
よいC#規約は、開発者を縛るものではなく、チームが安心してコードを書き、レビューし、長く保守していくための支えになります。

