C# namespaceの命名規則とは?基本ルールからフォルダ構成・NG例までわかりやすく解説

はじめに

C#で開発を進めていると、ほぼ必ず登場するのがnamespaceです。クラスを作成したときに自動で付与されることも多いため、最初は「とりあえずプロジェクト名と同じにしておけばよい」と考えがちです。

しかし、namespaceの命名規則が整理されていないと、プロジェクトが大きくなるにつれて、クラスの場所がわかりにくくなったり、似た名前の型が増えて混乱したり、usingが大量に増えて保守しづらくなったりします。

C#のnamespaceは、単なる飾りではありません。コードを論理的に分類し、名前の衝突を防ぎ、開発者が目的の型を見つけやすくするための重要な設計要素です。MicrosoftのC#ドキュメントでも、namespaceは関連する型をグループ化し、名前の衝突を防ぐ仕組みとして説明されています。Microsoft Learn

この記事では、C#におけるnamespaceの命名規則について、基本ルールからフォルダ構成との関係、実践的な構成例、避けるべきNG例までわかりやすく解説します。

1. C# namespaceとは?命名規則を理解する前の基礎知識

1-1. namespaceの役割:クラスや型の衝突を防ぐ仕組み

C#のnamespaceは、クラス、インターフェイス、構造体、列挙型などの型を整理するための名前空間です。

たとえば、次のように同じUserというクラス名があったとします。

C#
namespace MyApp.Customers
{
public class User
{
}
}

namespace MyApp.Admins
{
public class User
{
}
}

どちらもクラス名はUserですが、namespaceが異なるため、C#では別の型として扱われます。

C#
MyApp.Customers.User customerUser;
MyApp.Admins.User adminUser;

このように、namespaceを使うことで、同じ名前の型が存在しても衝突を避けられます。特に中規模以上のアプリケーションや、外部ライブラリを利用するプロジェクトでは、名前の衝突を防ぐことが重要になります。

1-2. namespaceとフォルダ・プロジェクト・アセンブリの違い

namespaceは、フォルダ、プロジェクト、アセンブリと混同されやすい概念です。

フォルダは、ファイルシステム上の物理的な配置です。たとえば、Services/Paymentsというフォルダは、ソースコードファイルを整理するための入れ物です。

プロジェクトは、.csprojファイルを中心としたビルド単位です。Webアプリケーション、クラスライブラリ、テストプロジェクトなどは、それぞれ別プロジェクトとして管理されることがあります。

アセンブリは、ビルド後に生成される.dll.exeなどの単位です。アセンブリ名とnamespace名は一致していることが多いですが、必ず一致しなければならないわけではありません。Microsoftの設計ガイドラインでも、DLL名はnamespaceの共通プレフィックスに基づけるとよいとされていますが、namespace名と完全一致する必要があるとはされていません。Microsoft Learn

一方、namespaceはコード上の論理的な分類です。

C#
namespace MyApp.Services.Payments
{
public class PaymentService
{
}
}

このnamespaceは、必ずしもMyApp/Services/Paymentsというフォルダに置かなければならないわけではありません。ただし、実務ではフォルダ構成とnamespaceをそろえることが一般的です。

1-3. 完全修飾名とusingディレクティブの関係

namespaceを含めた型の正式な名前を「完全修飾名」と呼びます。

たとえば、次のクラスがあるとします。

C#
namespace MyApp.Services.Payments
{
public class PaymentService
{
}
}

このクラスの完全修飾名は、次のようになります。

C#
MyApp.Services.Payments.PaymentService

毎回このように長い名前を書くのは大変です。そこで使うのがusingディレクティブです。

C#
using MyApp.Services.Payments;

var service = new PaymentService();

usingを指定すると、完全修飾名を書かなくても型名だけで参照できます。C#の公式ドキュメントでも、usingディレクティブはnamespace内に定義された型を完全修飾名なしで使えるようにする仕組みとして説明されています。Microsoft Learn

つまり、namespaceの命名がわかりやすいほど、usingを見ただけで「どの機能に関する型なのか」が判断しやすくなります。

1-4. namespaceを適切に設計するメリット

namespaceを適切に設計すると、次のようなメリットがあります。

まず、コードの所在がわかりやすくなります。MyApp.Services.Paymentsを見れば、支払い処理に関するサービスであることがすぐにわかります。

次に、名前の衝突を防ぎやすくなります。UserOrderRequestResponseのような一般的な型名でも、適切なnamespaceに分けることで混乱を避けられます。

また、プロジェクト全体の設計意図が伝わりやすくなります。DomainApplicationInfrastructureなどのnamespaceを使えば、クリーンアーキテクチャや層別設計の構造も読み取りやすくなります。

さらに、チーム開発でも保守性が上がります。新しいクラスをどこに置くべきか、どのnamespaceに含めるべきかの判断がしやすくなるため、コードのばらつきを防げます。

2. C# namespaceの基本的な命名規則

2-1. PascalCaseを使う

C#のnamespace名には、基本的にPascalCaseを使います。PascalCaseとは、単語の先頭を大文字にしてつなげる書き方です。

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

C#
namespace MyApp.Services
{
}
C#
namespace Contoso.ECommerce.Payments
{
}

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

C#
namespace myapp.services
{
}
C#
namespace my_app.services
{
}

C#では、namespaceも識別子の一種です。MicrosoftのC#命名規則でも、namespaceを含む識別子に対して一貫した命名規則を使うことが説明されています。Microsoft Learn

特別な理由がない限り、小文字だけ、snake_case、kebab-caseのような表記は避け、C#らしいPascalCaseで統一しましょう。

2-2. ドットで階層を区切る

C#のnamespaceでは、ドット.を使って階層を表します。

C#
namespace MyApp.Services.Payments
{
}

これは、次のような意味合いになります。

MyApp
└── Services
└── Payments

ドットで区切ることで、大きなカテゴリから小さなカテゴリへと段階的に分類できます。

たとえば、ECサイトであれば次のようなnamespaceが考えられます。

C#
namespace MyShop.Catalog
{
}

namespace MyShop.Orders
{
}

namespace MyShop.Payments
{
}

namespace MyShop.Shipping
{
}

さらに細かく分ける場合は、次のようにします。

C#
namespace MyShop.Orders.Commands
{
}

namespace MyShop.Orders.Queries
{
}

namespace MyShop.Orders.Services
{
}

ただし、階層を深くしすぎるとnamespaceが長くなり、かえって読みづらくなります。ドットによる階層化は便利ですが、必要以上に細かく分けないことが大切です。

2-3. 会社名・製品名・機能名を基本構成にする

C#のnamespace命名では、次のような構成がよく使われます。

会社名.製品名.機能名

Microsoftの.NET設計ガイドラインでも、namespace名の基本形として、会社名、製品名または技術名、機能名、サブnamespaceを組み合わせる形式が示されています。Microsoft Learn

例を挙げると、次のようになります。

C#
namespace Contoso.Inventory.Products
{
}
C#
namespace Fabrikam.Accounting.Reports
{
}
C#
namespace MyCompany.Crm.Customers
{
}

会社名や組織名を最上位に置くことで、他社製ライブラリや外部パッケージとの名前衝突を避けやすくなります。

ただし、社内アプリケーションや小規模な個人開発では、必ずしも会社名から始める必要はありません。その場合は、アプリケーション名やプロダクト名をルートnamespaceにすることが多いです。

C#
namespace TaskBoard.Tasks
{
}
C#
namespace BookManager.Authors
{
}

2-4. 安定した名前を使い、組織名や部署名に依存しない

namespace名には、できるだけ長期間変わらない名前を使いましょう。

たとえば、次のようなnamespaceは避けた方がよいです。

C#
namespace SalesTeam.OrderSystem
{
}
C#
namespace TokyoOffice.CustomerManagement
{
}

部署名、チーム名、拠点名、プロジェクトの一時的なコードネームなどは、将来変更される可能性があります。namespaceは多くのファイルや参照に影響するため、後から変更すると修正範囲が広くなりがちです。

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

C#
namespace Contoso.OrderManagement
{
}
C#
namespace Contoso.CustomerPortal
{
}

組織構造ではなく、製品、ドメイン、機能に基づいて命名すると、変更に強いnamespaceになります。

2-5. 省略形・略語・ハンガリアン記法を避ける

namespace名では、意味が伝わりにくい省略形や略語を避けましょう。

悪い例です。

C#
namespace MyApp.Svc.Pmt
{
}
C#
namespace MyApp.CustMgmt
{
}

書いた本人には意味がわかっても、他の開発者には伝わりにくいことがあります。

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

C#
namespace MyApp.Services.Payments
{
}
C#
namespace MyApp.CustomerManagement
{
}

また、strintclsのような型情報を名前に含めるハンガリアン記法も、namespace名には不要です。

C#
namespace MyApp.ClsServices
{
}

このような名前は、C#の一般的な命名規則から外れており、読みやすさも低下します。namespace名は、型情報ではなく「何に関するコードなのか」を表すようにしましょう。

2-6. 型名とnamespace名を衝突させない

namespace名と型名が同じになると、コードを読むときに混乱が生じます。

悪い例です。

C#
namespace MyApp.Payment
{
public class Payment
{
}
}

この場合、MyApp.Payment.Paymentという完全修飾名になり、Paymentがnamespaceなのかクラスなのかわかりにくくなります。

改善するなら、次のようにします。

C#
namespace MyApp.Payments
{
public class Payment
{
}
}

または、クラス名をより具体的にします。

C#
namespace MyApp.PaymentProcessing
{
public class PaymentProcessor
{
}
}

Microsoftのnamespace命名ガイドラインでも、namespace内の型名とnamespace名が衝突しないよう注意する考え方が示されています。Microsoft Learn

3. namespace名のおすすめ構成パターン

3-1. アプリケーション開発で使いやすい構成例

一般的なアプリケーション開発では、アプリケーション名をルートnamespaceにし、その下に機能や層を配置する構成が使いやすいです。

C#
namespace TaskBoard.Users
{
}

namespace TaskBoard.Tasks
{
}

namespace TaskBoard.Projects
{
}

namespace TaskBoard.Notifications
{
}

機能単位で分けると、どのnamespaceに何が含まれているかが直感的にわかります。

さらに層を分ける場合は、次のようにできます。

C#
namespace TaskBoard.Users.Controllers
{
}

namespace TaskBoard.Users.Services
{
}

namespace TaskBoard.Users.Repositories
{
}

ただし、すべての機能に必ずControllersServicesRepositoriesを作る必要はありません。小さな機能であれば、無理に階層を増やさず、シンプルに保つことも重要です。

3-2. ライブラリ開発で使いやすい構成例

ライブラリを開発する場合は、利用者から見たわかりやすさが特に重要です。会社名またはブランド名、ライブラリ名、機能名の順にすると整理しやすくなります。

C#
namespace Contoso.Validation
{
}

namespace Contoso.Validation.Rules
{
}

namespace Contoso.Validation.Results
{
}

NuGetで公開するライブラリの場合、他のライブラリとnamespaceが衝突しないようにする必要があります。そのため、UtilsCommonのような一般的すぎるルートnamespaceは避けましょう。

悪い例です。

C#
namespace Common
{
}
C#
namespace Utilities
{
}

良い例です。

C#
namespace Contoso.TextFormatting
{
}
C#
namespace YamatoSoft.CsvReader
{
}

ライブラリ利用者がusingを書いたときに、どのパッケージの機能なのか判断できる名前を意識しましょう。

3-3. 個人開発・小規模プロジェクトでの命名例

個人開発や小規模プロジェクトでは、過度に厳密な階層設計は不要です。まずはアプリケーション名をルートnamespaceにし、主要な機能ごとに分けるだけでも十分です。

C#
namespace MemoApp.Notes
{
}

namespace MemoApp.Tags
{
}

namespace MemoApp.Search
{
}

小規模なコンソールアプリなら、さらにシンプルでも問題ありません。

C#
namespace FileRenamer
{
}
C#
namespace ImageResizer
{
}

ただし、後から機能が増える可能性があるなら、最初から少しだけ拡張しやすい名前にしておくと安心です。

C#
namespace ImageResizer.Core
{
}

namespace ImageResizer.Processing
{
}

namespace ImageResizer.Settings
{
}

重要なのは、最初から大企業向けのような深いnamespaceにしないことです。プロジェクトの規模に合った命名にしましょう。

3-4. 複数プロジェクトを含むソリューションでの命名例

C#では、1つのソリューションに複数のプロジェクトを含めることがよくあります。

たとえば、次のような構成です。

OrderSystem.sln
├── OrderSystem.Web
├── OrderSystem.Application
├── OrderSystem.Domain
├── OrderSystem.Infrastructure
└── OrderSystem.Tests

この場合、namespaceもプロジェクト名に合わせるとわかりやすくなります。

C#
namespace OrderSystem.Web.Controllers
{
}
C#
namespace OrderSystem.Application.Orders
{
}
C#
namespace OrderSystem.Domain.Customers
{
}
C#
namespace OrderSystem.Infrastructure.Persistence
{
}
C#
namespace OrderSystem.Tests.Application.Orders
{
}

プロジェクト名とルートnamespaceをそろえることで、ファイルがどのプロジェクトに属しているかを推測しやすくなります。

ただし、すべてのnamespaceにプロジェクト名をそのまま含めるべきとは限りません。たとえば、公開ライブラリではアセンブリ名よりも利用者にとって自然なnamespaceを優先することがあります。

3-5. Domain・Application・Infrastructureなど層別設計での命名例

クリーンアーキテクチャやDDDを意識した設計では、層ごとにnamespaceを分けることがよくあります。

C#
namespace OrderSystem.Domain.Orders
{
}
C#
namespace OrderSystem.Application.Orders.Commands
{
}
C#
namespace OrderSystem.Application.Orders.Queries
{
}
C#
namespace OrderSystem.Infrastructure.Persistence
{
}
C#
namespace OrderSystem.Web.Controllers
{
}

この構成では、namespaceを見るだけで責務がわかります。

Domainには、エンティティ、値オブジェクト、ドメインサービスなど、ビジネスルールの中心となるコードを置きます。

Applicationには、ユースケース、コマンド、クエリ、アプリケーションサービスなどを置きます。

Infrastructureには、データベースアクセス、外部API連携、ファイル操作など、技術的な実装を置きます。

WebPresentationには、コントローラー、画面、APIエンドポイントなど、外部との入出力に関するコードを置きます。

このようにnamespaceを設計すると、依存関係の方向も管理しやすくなります。

4. namespaceとフォルダ構成の考え方

4-1. 基本はフォルダ構成とnamespaceをそろえる

C#では、フォルダ構成とnamespaceを必ず一致させなければならないわけではありません。しかし、実務では基本的にそろえることをおすすめします。

たとえば、次のフォルダにファイルを置く場合を考えます。

Services/Payments/PaymentService.cs

この場合、namespaceは次のようにすると自然です。

C#
namespace MyApp.Services.Payments;

public class PaymentService
{
}

フォルダとnamespaceが対応していれば、ファイルの場所とコード上の分類が一致します。これにより、コードを探すときの負担が減ります。

4-2. フォルダ構成とnamespaceを一致させるメリット

フォルダ構成とnamespaceを一致させるメリットは大きく3つあります。

1つ目は、ファイルを探しやすいことです。MyApp.Services.Payments.PaymentServiceという型を見たとき、Services/Paymentsフォルダにあると予想できます。

2つ目は、チーム内で配置ルールが統一されることです。新しいクラスを追加するときに、どこへ置くべきか迷いにくくなります。

3つ目は、IDEの補完やリファクタリングと相性がよいことです。Visual StudioやJetBrains RiderなどのIDEでは、フォルダとnamespaceの不一致を検出したり、namespaceを修正したりする機能があります。

フォルダ構成とnamespaceがばらばらだと、後からコードを読む人が「なぜこの場所にこのnamespaceなのか」を考えなければなりません。特別な理由がなければ、一致させるのが無難です。

4-3. フォルダ構成とnamespaceを分けてもよいケース

フォルダ構成とnamespaceは、常に完全一致させる必要はありません。分けてもよいケースもあります。

たとえば、実装上の都合でフォルダを分けているだけの場合です。

Generated/

自動生成コードをGeneratedフォルダにまとめている場合でも、namespaceに必ずGeneratedを含める必要はありません。

C#
namespace MyApp.Api.Client;

また、機能単位ではなく、ファイル種別や生成元でフォルダを分けている場合もあります。

Models/
Generated/
Partial/

このような場合は、フォルダ名をそのままnamespaceに反映すると、かえって意味がわかりにくくなることがあります。

重要なのは、フォルダとnamespaceを分ける理由が明確であり、チーム内で共有されていることです。単なる不統一にならないよう注意しましょう。

4-4. Services/Paymentsフォルダのnamespace例

具体例として、Services/Paymentsフォルダに支払い処理関連のクラスを置く場合を考えます。

MyApp
└── Services
└── Payments
├── PaymentService.cs
├── PaymentRequest.cs
├── PaymentResult.cs
└── IPaymentGateway.cs

この場合、namespaceは次のようにできます。

C#
namespace MyApp.Services.Payments;

public class PaymentService
{
}
C#
namespace MyApp.Services.Payments;

public class PaymentRequest
{
}
C#
namespace MyApp.Services.Payments;

public interface IPaymentGateway
{
}

関連する型を同じnamespaceにまとめることで、using MyApp.Services.Payments;を追加するだけで支払い関連の型を扱えるようになります。

さらに外部決済サービスごとに分けるなら、次のようなnamespaceも考えられます。

C#
namespace MyApp.Services.Payments.Stripe;
C#
namespace MyApp.Services.Payments.PayPal;

ただし、サービス名を直接namespaceに含めると、将来別のサービスに差し替えるときに変更が発生する可能性があります。外部サービス固有の実装であれば問題ありませんが、アプリケーション全体の抽象的なnamespaceには、特定ベンダー名を入れすぎない方がよいでしょう。

4-5. Visual StudioやIDEでnamespaceを管理するポイント

Visual StudioやRiderなどのIDEを使うと、namespaceの管理が楽になります。

新しいクラスを追加するとき、プロジェクトのルートnamespaceとフォルダ構成に基づいてnamespaceが自動生成されることがあります。この仕組みを利用すれば、手作業によるnamespaceのばらつきを減らせます。

また、ファイルを別フォルダに移動したときは、namespaceも合わせて変更するか確認しましょう。IDEによっては、namespaceとフォルダ構成の不一致を警告し、修正候補を表示してくれます。

.editorconfigを使えば、ファイルスコープnamespaceを使うか、ブロック形式namespaceを使うかといったスタイルもプロジェクト単位で統一できます。Microsoftのコードスタイル規則には、ファイルスコープnamespaceとブロック形式namespaceの使用方針を設定するルールも用意されています。Microsoft Learn

5. C#でnamespaceを宣言する書き方

5-1. 従来のブロック形式のnamespace宣言

従来のC#では、namespaceはブロック形式で書くのが一般的でした。

C#
namespace MyApp.Services
{
public class UserService
{
public void CreateUser()
{
}
}
}

ブロック形式では、namespaceの中にクラスやインターフェイスを波かっこで囲んで記述します。

この書き方は現在でも有効であり、複数のnamespaceを1つのファイルに書く場合や、既存コードとの統一を重視する場合に使われます。

ただし、階層が深いコードではインデントが増えやすく、ファイル全体が右に寄って見えることがあります。

5-2. C# 10以降のファイルスコープnamespace宣言

C# 10以降では、ファイルスコープnamespace宣言が使えます。ファイルスコープnamespaceでは、ファイルの先頭にnamespaceを1行で書きます。

C#
namespace MyApp.Services;

public class UserService
{
public void CreateUser()
{
}
}

この書き方では、ファイル全体が指定したnamespaceに属します。MicrosoftのC# 10仕様でも、ファイルスコープnamespaceはファイル内容全体を先頭で宣言したnamespaceに含める構文として説明されています。Microsoft Learn

ファイルスコープnamespaceのメリットは、インデントが浅くなり、コードが読みやすくなることです。1ファイルに1つのnamespaceを書く一般的なスタイルであれば、ファイルスコープnamespaceは非常に相性がよいです。

5-3. 1ファイルに複数namespaceを書くべきか

C#では、1つのファイルに複数のnamespaceを書くこともできます。公式ドキュメントでも、同じnamespaceを複数の宣言に分けて定義できることが説明されています。Microsoft Learn

例です。

C#
namespace MyApp.Customers
{
public class Customer
{
}
}

namespace MyApp.Orders
{
public class Order
{
}
}

ただし、実務では1ファイルに複数namespaceを書くことはあまりおすすめしません。ファイルの責務が曖昧になり、目的の型を探しにくくなるためです。

基本的には、1ファイルに1つの主要な型、1つのnamespaceという構成が扱いやすいです。

例外として、自動生成コードや、非常に小さな関連型をまとめる場合などは、複数namespaceが使われることもあります。しかし、通常のアプリケーションコードでは避けた方が無難です。

5-4. using・global using・static usingとの使い分け

namespaceと関連して理解しておきたいのが、usingglobal usingstatic usingです。

通常のusingは、特定のファイルでnamespaceを省略して使うためのものです。

C#
using MyApp.Services.Payments;

var service = new PaymentService();

global usingは、プロジェクト全体で有効なusingです。

C#
global using MyApp.Services.Payments;

複数のファイルで頻繁に使うnamespaceがある場合に便利です。ただし、何でもglobal usingにすると、どの型がどこから来ているのか見えにくくなるため注意が必要です。

static usingは、staticメンバーを型名なしで使うためのものです。

C#
using static System.Math;

var value = Sqrt(25);

便利ですが、多用するとメソッドの出どころがわかりにくくなります。特にチーム開発では、読みやすさを優先して慎重に使いましょう。

5-5. namespace aliasを使うケース

namespace aliasを使うと、長いnamespaceや名前が衝突する型に別名を付けられます。

C#
using PaymentModels = MyApp.Services.Payments.Models;

var request = new PaymentModels.PaymentRequest();

また、同じ型名が複数のnamespaceに存在する場合にも便利です。

C#
using CustomerUser = MyApp.Customers.User;
using AdminUser = MyApp.Admins.User;

CustomerUser customer = new CustomerUser();
AdminUser admin = new AdminUser();

ただし、aliasはあくまで補助的な手段です。頻繁にaliasが必要になる場合は、namespaceや型名の設計自体がわかりにくくなっている可能性があります。

6. やってはいけないnamespaceのNG例

6-1. 小文字・snake_case・不統一な表記を使う

C#のnamespaceでは、PascalCaseで統一するのが基本です。

悪い例です。

C#
namespace myapp.services
{
}
C#
namespace MyApp.payment_services
{
}
C#
namespace MyApp.Paymentservices
{
}

このような表記が混在すると、コード全体の統一感が失われます。

良い例です。

C#
namespace MyApp.Services
{
}
C#
namespace MyApp.PaymentServices
{
}

namespace名は、プロジェクト全体で一貫していることが重要です。表記ゆれは検索性や可読性にも影響するため、早い段階でルールを決めておきましょう。

6-2. バージョン番号をnamespaceに含める

namespaceにバージョン番号を含めるのは、基本的には避けた方がよいです。

悪い例です。

C#
namespace MyApp.Services.V1
{
}
C#
namespace MyApp.Api.Version2
{
}

APIのバージョン管理など、一部の場面ではV1V2を使うことがあります。しかし、内部実装のnamespaceにバージョン番号を入れると、将来の変更時にnamespaceが増え続けて複雑になりがちです。

特にライブラリでは、バージョンはパッケージバージョンやアセンブリバージョンで管理するのが一般的です。namespaceは、機能や責務を表すために使いましょう。

例外的に、公開APIの互換性維持のためにnamespaceを分ける場合はあります。

C#
namespace MyProduct.Api.V1
{
}
C#
namespace MyProduct.Api.V2
{
}

ただし、この場合も明確な設計意図が必要です。

6-3. 部署名・チーム名など変わりやすい名前を使う

部署名やチーム名をnamespaceに含めると、組織変更のたびに名前が古くなる可能性があります。

悪い例です。

C#
namespace SalesDepartment.OrderSystem
{
}
C#
namespace TeamAlpha.CustomerPortal
{
}

組織名やチーム名は、開発中に変わることがあります。namespaceに含めてしまうと、実態と名前が合わなくなり、将来的なリファクタリングの原因になります。

良い例です。

C#
namespace OrderSystem.Sales
{
}
C#
namespace CustomerPortal.Accounts
{
}

namespaceは、組織構造ではなく、プロダクトや業務領域、機能を基準に命名するのがおすすめです。

6-4. SystemやMicrosoftなど既存namespaceと紛らわしい名前を使う

SystemMicrosoftなど、既存の有名なnamespaceと紛らわしい名前は避けましょう。

悪い例です。

C#
namespace System.Helpers
{
}
C#
namespace Microsoft.Tools
{
}

このようなnamespaceは、標準ライブラリや公式ライブラリと誤解される可能性があります。また、型名の衝突やusingの混乱を招くこともあります。

自社や自分のプロダクトであることがわかる名前を使いましょう。

C#
namespace Contoso.Tools
{
}
C#
namespace MyCompany.SystemUtilities
{
}

Microsoftの設計ガイドラインでも、Systemなどのコアnamespaceに含まれる型と競合する名前を避ける考え方が示されています。Microsoft Learn

6-5. フォルダ階層を深くしすぎてnamespaceが長くなる

フォルダ構成を細かくしすぎると、namespaceも長くなりすぎることがあります。

悪い例です。

C#
namespace MyApp.Features.Orders.UseCases.CreateOrder.Command.Handlers.Internal
{
}

このようなnamespaceは、分類が細かすぎて読むのが大変です。完全修飾名も長くなり、コードの見通しが悪くなります。

改善例です。

C#
namespace MyApp.Orders.Commands
{
}
C#
namespace MyApp.Application.Orders
{
}

namespaceは細かければよいわけではありません。分類の粒度は、コードを探しやすくするために必要な範囲にとどめましょう。

6-6. クラス名と同じnamespace名にする

クラス名とnamespace名が同じになると、可読性が下がります。

悪い例です。

C#
namespace MyApp.Customer
{
public class Customer
{
}
}

この場合、完全修飾名は次のようになります。

C#
MyApp.Customer.Customer

意味は通じますが、読みやすいとは言えません。

良い例です。

C#
namespace MyApp.Customers
{
public class Customer
{
}
}

または、より具体的にします。

C#
namespace MyApp.CustomerManagement
{
public class Customer
{
}
}

namespaceはカテゴリ、クラス名は具体的な型を表すように分けると自然です。

7. namespace設計の実践例

7-1. 悪い例と良い例の比較

まず、悪い例を見てみましょう。

C#
namespace app
{
public class UserService
{
}
}

namespace app.common
{
public class Utils
{
}
}

namespace SalesTeam.User
{
public class User
{
}
}

問題点は次のとおりです。

appが小文字で、C#の一般的な命名規則に合っていません。commonUtilsが曖昧で、何を扱うnamespaceなのかわかりにくいです。SalesTeamのような変わりやすい組織名が含まれています。また、User.Userのようにnamespace名と型名が重複しやすい構造になっています。

改善例です。

C#
namespace CustomerPortal.Users
{
public class UserService
{
}
}

namespace CustomerPortal.Shared.Validation
{
public class ValidationResult
{
}
}

namespace CustomerPortal.Accounts
{
public class User
{
}
}

このように、プロダクト名、機能名、責務がわかる名前にすると、コードの意図が伝わりやすくなります。

7-2. Webアプリケーションでのnamespace構成例

ASP.NET CoreなどのWebアプリケーションでは、プレゼンテーション、アプリケーションロジック、データアクセスなどを分けることがよくあります。

例です。

CustomerPortal.Web
├── Controllers
├── Models
├── ViewModels
└── Middlewares

namespaceは次のようにできます。

C#
namespace CustomerPortal.Web.Controllers
{
}
C#
namespace CustomerPortal.Web.ViewModels
{
}
C#
namespace CustomerPortal.Web.Middlewares
{
}

アプリケーション層を別プロジェクトにする場合は、次のようにします。

C#
namespace CustomerPortal.Application.Customers
{
}
C#
namespace CustomerPortal.Application.Orders
{
}

データアクセスは次のように分けられます。

C#
namespace CustomerPortal.Infrastructure.Persistence
{
}
C#
namespace CustomerPortal.Infrastructure.ExternalServices
{
}

Webアプリケーションでは、ControllersViewModelsのような技術的な分類と、CustomersOrdersのような機能的な分類をどう組み合わせるかがポイントです。

小規模なら技術別、大規模なら機能別のnamespaceにすると管理しやすいことが多いです。

7-3. クリーンアーキテクチャでのnamespace構成例

クリーンアーキテクチャでは、依存関係の方向を明確にするため、層ごとにプロジェクトやnamespaceを分けます。

例です。

OrderSystem.Domain
OrderSystem.Application
OrderSystem.Infrastructure
OrderSystem.Web

Domain層です。

C#
namespace OrderSystem.Domain.Orders
{
public class Order
{
}
}
C#
namespace OrderSystem.Domain.Customers
{
public class Customer
{
}
}

Application層です。

C#
namespace OrderSystem.Application.Orders.CreateOrder
{
public class CreateOrderCommand
{
}
}
C#
namespace OrderSystem.Application.Orders.GetOrder
{
public class GetOrderQuery
{
}
}

Infrastructure層です。

C#
namespace OrderSystem.Infrastructure.Persistence
{
public class AppDbContext
{
}
}

Web層です。

C#
namespace OrderSystem.Web.Controllers
{
public class OrdersController
{
}
}

このようにnamespaceを分けると、どのコードがどの層に属しているかが明確になります。依存関係のルールも把握しやすくなります。

7-4. NuGet公開を想定したライブラリのnamespace構成例

NuGetで公開するライブラリでは、利用者がusingしたときに自然に理解できるnamespaceを設計する必要があります。

たとえば、CSV読み書きライブラリなら次のような構成が考えられます。

C#
namespace Contoso.Csv
{
}
C#
namespace Contoso.Csv.Reading
{
}
C#
namespace Contoso.Csv.Writing
{
}
C#
namespace Contoso.Csv.Configuration
{
}

公開APIとしてよく使われる型は、あまり深いnamespaceに置かない方が使いやすいです。

C#
namespace Contoso.Csv
{
public class CsvReader
{
}

public class CsvWriter
{
}
}

内部的な詳細実装は、サブnamespaceに分けてもよいでしょう。

C#
namespace Contoso.Csv.Parsing
{
}
C#
namespace Contoso.Csv.Internal
{
}

ただし、Internalというnamespaceに置いたからといって、外部からアクセスできなくなるわけではありません。外部に公開したくない型は、internalアクセス修飾子を使って制御しましょう。

7-5. テストプロジェクトのnamespace構成例

テストプロジェクトでは、テスト対象のnamespaceに対応させるとわかりやすくなります。

本体コードが次のようなnamespaceだとします。

C#
namespace OrderSystem.Application.Orders
{
public class OrderService
{
}
}

テストコードは次のようにできます。

C#
namespace OrderSystem.Tests.Application.Orders
{
public class OrderServiceTests
{
}
}

または、テストプロジェクト名に合わせて次のようにしてもよいです。

C#
namespace OrderSystem.Application.Tests.Orders
{
}

どちらでも構いませんが、プロジェクト内で統一することが重要です。

テスト対象とテストコードの対応をわかりやすくしたい場合は、次のように同じ階層を再現する方法が便利です。

OrderSystem.Application
└── Orders
└── OrderService.cs

OrderSystem.Application.Tests
└── Orders
└── OrderServiceTests.cs

namespaceもこれに合わせます。

C#
namespace OrderSystem.Application.Tests.Orders;

テストコードは後から増えやすいため、最初から命名ルールを決めておくと管理しやすくなります。

8. 既存プロジェクトのnamespaceを整理・変更する方法

8-1. 現在のnamespace構成を確認する

既存プロジェクトのnamespaceを整理する場合、まずは現在の構成を確認しましょう。

確認するポイントは次のとおりです。

どのnamespaceが使われているか。

フォルダ構成とnamespaceが一致しているか。

小文字、snake_case、省略形などの表記ゆれがないか。

CommonUtilsHelpersのような曖昧なnamespaceが増えすぎていないか。

クラス名とnamespace名が重複していないか。

Visual StudioやRiderの検索機能を使って、namespace でプロジェクト全体を検索すると一覧しやすいです。

また、コマンドラインで確認するなら、次のように検索することもできます。

Bash
grep -R "namespace " .

Windows環境ならPowerShellで次のように確認できます。

PowerShell
Get-ChildItem -Recurse -Filter *.cs | Select-String "namespace "

まずは現状を把握し、どこから修正するべきかを決めましょう。

8-2. フォルダ構成とnamespaceのずれを修正する

次に、フォルダ構成とnamespaceのずれを修正します。

たとえば、次のファイルがあるとします。

Services/Payments/PaymentService.cs

しかし、namespaceが次のようになっている場合です。

C#
namespace MyApp.Payment
{
}

この場合、フォルダ構成に合わせて次のように修正します。

C#
namespace MyApp.Services.Payments
{
}

または、namespaceの方が正しい設計であれば、フォルダを移動します。

重要なのは、どちらを正とするかを決めることです。何となく両方を少しずつ直すと、かえって不統一が増えてしまいます。

8-3. IDEのリファクタリング機能で安全に変更する

namespaceを変更すると、その型を参照しているすべてのコードに影響します。手作業で一括置換すると、意図しない箇所まで変更してしまう危険があります。

安全に変更するには、IDEのリファクタリング機能を使いましょう。

Visual StudioやRiderでは、namespaceの変更、型の移動、usingの更新などを支援する機能があります。ファイルを移動したときにnamespaceの修正候補を表示してくれる場合もあります。

特に大きなプロジェクトでは、一度にすべてを変更するのではなく、機能単位、プロジェクト単位で少しずつ進めるのがおすすめです。

変更後は、必ずビルドとテストを実行しましょう。

Bash
dotnet build
dotnet test

namespace変更はコンパイルエラーとして検出されやすい修正ですが、リフレクションや設定ファイル、シリアライズ名などに影響する場合もあるため注意が必要です。

8-4. usingの不要・重複を整理する

namespaceを整理した後は、usingも見直しましょう。

不要なusingが残っていると、コードが読みにくくなります。また、同じような名前の型が複数ある場合、意図しない型を参照してしまう可能性もあります。

整理前の例です。

C#
using MyApp.Services;
using MyApp.Services.Payments;
using MyApp.Common;
using MyApp.Utils;
using System;
using System.Collections.Generic;

実際に必要なものだけに整理します。

C#
using MyApp.Services.Payments;

IDEの「不要なusingの削除」機能を使うと効率的です。プロジェクトによっては、保存時に自動でusingを整理する設定もできます。

global usingを使っている場合は、個別ファイルのusingだけでなく、プロジェクト全体に適用されるusingも確認しましょう。

8-5. チーム開発では命名ルールをドキュメント化する

チーム開発では、namespaceの命名ルールをドキュメント化しておくことが重要です。

たとえば、次のようなルールを決めます。

- namespaceはPascalCaseにする
- ルートnamespaceはプロジェクト名に合わせる
- 基本的にフォルダ構成とnamespaceを一致させる
- Common、Utils、Helpersを安易に使わない
- 部署名やチーム名をnamespaceに含めない
- 1ファイルに複数namespaceを書かない
- 新規コードではファイルスコープnamespaceを使う

このようなルールをREADME、開発ガイドライン、.editorconfigなどにまとめておくと、新しいメンバーも迷いにくくなります。

namespaceの命名規則は、最初は細かい話に見えるかもしれません。しかし、プロジェクトが大きくなるほど、統一されたルールの価値は大きくなります。

9. C# namespace命名規則に関するよくある質問

9-1. namespaceは必ずフォルダと一致させるべき?

必ず一致させる必要はありません。ただし、基本的には一致させることをおすすめします。

フォルダ構成とnamespaceが一致していると、ファイルの場所とコード上の分類が対応するため、コードを探しやすくなります。

たとえば、次のフォルダにあるファイルは、

Services/Payments/PaymentService.cs

次のnamespaceにすると自然です。

C#
namespace MyApp.Services.Payments;

ただし、自動生成コードや特殊な実装フォルダなど、フォルダ名をnamespaceに含めない方がわかりやすい場合もあります。大切なのは、プロジェクト内でルールが統一されていることです。

9-2. プロジェクト名とnamespace名は同じにするべき?

多くの場合、プロジェクト名とルートnamespaceは同じか、かなり近い名前にするのがおすすめです。

たとえば、プロジェクト名がOrderSystem.Applicationなら、namespaceも次のようにすると自然です。

C#
namespace OrderSystem.Application.Orders;

ただし、必ず一致させる必要はありません。特にライブラリ開発では、プロジェクト名やアセンブリ名よりも、利用者にとってわかりやすいnamespaceを優先することがあります。

重要なのは、プロジェクト名、アセンブリ名、namespace名の関係がチーム内で理解されていることです。

9-3. namespaceに複数形を使ってもよい?

使っても問題ありません。むしろ、カテゴリを表すnamespaceでは複数形が自然な場合があります。

たとえば、次のようなnamespaceはよく使われます。

C#
namespace MyApp.Users;
C#
namespace MyApp.Orders;
C#
namespace MyApp.Services;

一方で、概念や機能名として単数形が自然な場合もあります。

C#
namespace MyApp.Authentication;
C#
namespace MyApp.Configuration;
C#
namespace MyApp.Logging;

複数形か単数形かに絶対的な正解はありません。大切なのは、意味が自然であり、プロジェクト内で統一されていることです。

9-4. ファイルスコープnamespaceとブロック形式はどちらを使うべき?

新しいC#プロジェクトでは、ファイルスコープnamespaceを使うことが多くなっています。

C#
namespace MyApp.Services;

public class UserService
{
}

インデントが浅くなり、1ファイル1namespaceの構成と相性がよいためです。

一方、既存プロジェクトがブロック形式で統一されている場合は、無理に混在させない方がよいです。

C#
namespace MyApp.Services
{
public class UserService
{
}
}

どちらの形式もC#で利用できます。重要なのは、プロジェクト内でスタイルを統一することです。

9-5. namespace名を後から変更しても問題ない?

変更は可能ですが、影響範囲に注意が必要です。

namespaceを変更すると、そのnamespace内の型を参照しているコードのusingや完全修飾名も変わります。IDEのリファクタリング機能を使えば多くの修正は自動化できますが、すべての影響を完全に把握できるとは限りません。

特に注意すべきなのは、次のようなケースです。

設定ファイルに型名を文字列で書いている場合。

リフレクションで完全修飾名を使っている場合。

シリアライズやデシリアライズに型名が関係している場合。

外部に公開しているライブラリのnamespaceを変更する場合。

社内アプリケーションであれば比較的変更しやすいですが、公開ライブラリでは破壊的変更になる可能性があります。変更する場合は、ビルドとテストを必ず実行し、必要に応じて移行手順も用意しましょう。

まとめ

C#のnamespaceは、クラスや型を整理し、名前の衝突を防ぎ、コードの見通しをよくするための重要な仕組みです。単に自動生成された名前をそのまま使うのではなく、プロジェクト全体の設計に合わせて命名することが大切です。

基本的な命名規則としては、PascalCaseを使い、ドットで階層を区切り、会社名・製品名・機能名を基準に構成します。部署名やチーム名のように変わりやすい名前、意味の伝わりにくい省略形、SystemMicrosoftと紛らわしい名前は避けましょう。

また、フォルダ構成とnamespaceは基本的にそろえるのがおすすめです。必須ではありませんが、ファイルの場所とコード上の分類が一致していると、保守性が大きく向上します。

C# 10以降では、ファイルスコープnamespaceを使うことで、よりシンプルにnamespaceを宣言できます。ただし、既存プロジェクトではブロック形式との混在に注意し、チームでスタイルを統一することが重要です。

namespaceの設計に迷ったら、次のポイントを確認しましょう。

- 名前から役割がわかるか
- PascalCaseで統一されているか
- フォルダ構成と対応しているか
- 変わりやすい組織名に依存していないか
- 型名とnamespace名が衝突していないか
- 深すぎる階層になっていないか

namespaceの命名規則は、プロジェクト初期に整えておくほど効果があります。読みやすく、探しやすく、変更しやすいC#コードを書くために、namespace設計を意識しておきましょう。