C# namespaceとは?使い方・役割・エラー対処まで初心者向けにわかりやすく解説

はじめに

C#でクラスを作成していると、よく出てくるのがnamespaceです。

C#
namespace MyApp.Models
{
public class User
{
public string Name { get; set; } = "";
}
}

初心者のうちは、「とりあえず自動生成されるもの」「書かなくても動くことがあるもの」という印象を持ちやすいですが、namespaceはC#でコードを整理するうえでとても重要な仕組みです。

namespaceを理解すると、次のようなことがわかるようになります。

  • クラスをどこに配置すればよいか

  • usingがなぜ必要なのか

  • 「型または名前空間の名前が見つかりません」というエラーの原因

  • 同じクラス名を安全に使い分ける方法

  • プロジェクトが大きくなっても見通しよく管理する方法

この記事では、C#のnamespaceについて、基本的な使い方からエラー対処、設計の考え方まで初心者向けにわかりやすく解説します。

1. C#のnamespaceとは?初心者向けに役割をわかりやすく解説

1-1. namespaceは「クラスや型を整理するための名前の箱」

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

たとえば、アプリケーションの中に次のようなクラスがあるとします。

C#
public class User
{
}

public class Product
{
}

public class Order
{
}

小さなプログラムであれば、このままでも問題ありません。しかし、プロジェクトが大きくなると、ユーザー関連、商品関連、注文関連など、コードの種類が増えて管理しにくくなります。

そこでnamespaceを使います。

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

namespace MyApp.Products
{
public class Product
{
}
}

namespace MyApp.Orders
{
public class Order
{
}
}

このようにnamespaceを使うことで、「このクラスはユーザー関連」「このクラスは商品関連」といった分類がしやすくなります。

namespaceは、ファイルを整理するフォルダのようなものだと考えるとイメージしやすいです。ただし、実際のフォルダと完全に同じものではありません。namespaceはあくまでC#のコード上で型を分類するための名前です。

1-2. namespaceが必要になる理由:名前の衝突を防ぐ

namespaceの大きな役割は、名前の衝突を防ぐことです。

たとえば、アプリケーションの中で「ユーザー画面用のUserクラス」と「データベース用のUserクラス」を作りたい場合があります。

C#
public class User
{
}

同じ場所に同じ名前のUserクラスを2つ定義すると、C#はどちらのUserを指しているのか判断できません。

そこで、namespaceを分けます。

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

namespace MyApp.Entities
{
public class User
{
}
}

この場合、2つのUserクラスは別物として扱われます。

C#
MyApp.ViewModels.User viewUser = new MyApp.ViewModels.User();
MyApp.Entities.User entityUser = new MyApp.Entities.User();

同じUserという名前でも、所属するnamespaceが違えば区別できます。

つまり、namespaceは「同じ名前のクラスがあっても、分類名を付けることで区別できるようにする仕組み」です。

1-3. C#ではすべての型が何らかのnamespaceに属している

C#のクラスや型は、基本的に何らかのnamespaceに属します。

たとえば、C#でよく使うConsoleクラスはSystem名前空間にあります。

C#
System.Console.WriteLine("Hello");

List<T>System.Collections.Generic名前空間にあります。

C#
System.Collections.Generic.List<string> names = new System.Collections.Generic.List<string>();

普段は次のようにusingを書くため、毎回完全な名前を書かずに済んでいます。

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

Console.WriteLine("Hello");

List<string> names = new List<string>();

また、自分で作成したクラスも、明示的にnamespaceを書けばその名前空間に属します。

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

一方、namespaceを書かずにクラスを定義した場合、その型は「グローバル名前空間」に属します。

C#
public class User
{
}

これは小さなサンプルでは動作しますが、実際のアプリケーションではクラスの整理が難しくなるため、通常は明示的にnamespaceを書くことが推奨されます。

1-4. namespaceを使うとコードの見通しがよくなる

namespaceを適切に使うと、コードの見通しがよくなります。

たとえば、次のような構成にすると、クラスの役割がわかりやすくなります。

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

namespace MyApp.Services
{
public class UserService
{
}
}

namespace MyApp.Repositories
{
public class UserRepository
{
}
}

このように分けると、名前を見ただけで役割を推測できます。

  • MyApp.Models:データ構造を表すクラス

  • MyApp.Services:処理やビジネスロジックを担当するクラス

  • MyApp.Repositories:データアクセスを担当するクラス

プロジェクトが大きくなるほど、namespaceによる整理は重要になります。

特にチーム開発では、誰が見てもクラスの場所や役割がわかるようにすることが大切です。namespaceを適切に設計しておくと、保守しやすいC#コードになります。

2. C# namespaceの基本的な書き方

2-1. ブロックスコープ形式のnamespace

C#で昔から使われている基本的な書き方が、ブロックスコープ形式のnamespaceです。

C#
namespace MyApp.Models
{
public class User
{
public string Name { get; set; } = "";
}
}

namespaceの後に名前を書き、波かっこ{ }の中にクラスなどを定義します。

構造は次のようになります。

C#
namespace 名前空間名
{
class クラス名
{
}
}

この形式では、波かっこの中に書いた型が、そのnamespaceに属します。

複数のクラスを書くこともできます。

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

public class Product
{
}

public class Order
{
}
}

ブロックスコープ形式は、昔から広く使われているため、多くのC#コードで見かけます。

2-2. ファイルスコープ形式のnamespace

C# 10以降では、ファイルスコープ形式のnamespaceが使えます。

C#
namespace MyApp.Models;

public class User
{
public string Name { get; set; } = "";
}

ブロックスコープ形式との違いは、namespaceの後にセミコロン;を書く点です。

C#
namespace 名前空間名;

この書き方をすると、そのファイル内の型はすべて指定したnamespaceに属します。

たとえば、次のコードではUserProductがどちらもMyApp.Models名前空間に属します。

C#
namespace MyApp.Models;

public class User
{
}

public class Product
{
}

ファイルスコープ形式のメリットは、インデントが浅くなり、コードがすっきりすることです。

ブロックスコープ形式の場合は、クラス全体がnamespaceの波かっこの中に入るため、インデントが1段深くなります。

C#
namespace MyApp.Models
{
public class User
{
public string Name { get; set; } = "";
}
}

ファイルスコープ形式では、次のように書けます。

C#
namespace MyApp.Models;

public class User
{
public string Name { get; set; } = "";
}

現在のC#では、シンプルなファイルではファイルスコープ形式がよく使われます。

2-3. namespaceの中にclassを書く基本構造

namespaceの中には、class以外にもさまざまな型を定義できます。

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

public struct Point
{
}

public interface IRepository
{
}

public enum UserStatus
{
Active,
Inactive
}
}

主に定義できるものは次のような型です。

  • class

  • struct

  • interface

  • enum

  • record

  • delegate

初心者がまず覚えるべき基本形は、次の形です。

C#
namespace MyApp.Models
{
public class User
{
public string Name { get; set; } = "";
}
}

別の場所からこのUserクラスを使う場合は、usingを使います。

C#
using MyApp.Models;

User user = new User();
user.Name = "Taro";

または、完全修飾名で書くこともできます。

C#
MyApp.Models.User user = new MyApp.Models.User();

2-4. namespace名にドットを使う書き方

namespace名にはドット.を使って階層のように表現できます。

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

この場合、MyAppの中にModelsがあるように見えます。

さらに細かく分けることもできます。

C#
namespace MyApp.Features.Users.Models
{
public class User
{
}
}

ドットを使うと、プロジェクト内の機能や役割を分類しやすくなります。

よくある例は次のような名前です。

C#
namespace MyApp.Controllers
{
}

namespace MyApp.Models
{
}

namespace MyApp.Services
{
}

namespace MyApp.Repositories
{
}

namespace MyApp.Utilities
{
}

ただし、ドットが多すぎると名前が長くなり、逆に読みにくくなります。

C#
namespace MyApp.Features.Users.Profile.Settings.Validation.Rules
{
}

このように深すぎるnamespaceは、使う側のコードも長くなります。適度な階層にすることが大切です。

2-5. namespaceを省略した場合はどうなる?

C#では、namespaceを書かずにクラスを定義することもできます。

C#
public class User
{
public string Name { get; set; } = "";
}

この場合、Userクラスはグローバル名前空間に属します。

小さな学習用コードや短いサンプルでは問題ありません。しかし、実際のアプリケーションでは、namespaceを省略すると次のような問題が起きやすくなります。

  • クラスの分類がわかりにくい

  • 名前の衝突が起きやすい

  • 他のファイルから使うときに整理しにくい

  • プロジェクトが大きくなると管理が難しくなる

そのため、実務では基本的にnamespaceを書くのが一般的です。

特にVisual Studioや.NETのテンプレートでプロジェクトを作成すると、多くの場合、プロジェクト名に基づいたnamespaceが自動で付与されます。

C#
namespace SampleApp;

public class User
{
}

初心者のうちは、自動生成されたnamespaceをそのまま使いながら、プロジェクト構成に合わせて少しずつ理解していくとよいでしょう。

3. namespaceとusingの違い

3-1. namespaceは「定義するもの」、usingは「使いやすくするもの」

C#初心者が混乱しやすいのが、namespaceusingの違いです。

簡単に言うと、次のような違いがあります。

namespaceは、クラスや型をどこに所属させるかを定義するものです。

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

一方、usingは、他のnamespaceにある型を短い名前で使えるようにするものです。

C#
using MyApp.Models;

User user = new User();

usingがない場合は、完全な名前で書く必要があります。

C#
MyApp.Models.User user = new MyApp.Models.User();

つまり、namespaceは「型を整理するための場所を作るもの」、usingは「その場所にある型を使いやすくするもの」です。

3-2. usingディレクティブの基本的な使い方

usingディレクティブは、ファイルの先頭に書くのが一般的です。

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

namespace MyApp;

public class Program
{
public static void Main()
{
Console.WriteLine("Hello");

List<string> names = new List<string>();

User user = new User();
}
}

このコードでは、次のnamespaceを使えるようにしています。

C#
using System;

System名前空間にあるConsoleを短く書けます。

C#
Console.WriteLine("Hello");
C#
using System.Collections.Generic;

System.Collections.Generic名前空間にあるList<T>を短く書けます。

C#
List<string> names = new List<string>();
C#
using MyApp.Models;

自作のUserクラスを短く書けます。

C#
User user = new User();

usingは、クラスを読み込む命令ではありません。あくまで、名前空間を省略して書けるようにするためのものです。

3-3. 完全修飾名で呼び出す方法

usingを使わずに、namespaceを含めた完全な名前で型を指定することもできます。

これを完全修飾名と呼びます。

たとえば、System.Consoleは完全修飾名です。

C#
System.Console.WriteLine("Hello");

List<T>も完全修飾名で書けます。

C#
System.Collections.Generic.List<string> names =
new System.Collections.Generic.List<string>();

自作クラスでも同じです。

C#
MyApp.Models.User user = new MyApp.Models.User();

完全修飾名を使うと、どのnamespaceの型を使っているのかが明確になります。

ただし、毎回書くとコードが長くなります。そのため、通常はusingを使って短く書きます。

C#
using MyApp.Models;

User user = new User();

完全修飾名は、主に次のような場合に使います。

  • 同じクラス名が複数あって区別したいとき

  • 一時的にどの型を使っているか明確にしたいとき

  • usingを増やしたくないとき

3-4. usingを使うべきケース・使わない方がよいケース

usingは便利ですが、何でも追加すればよいわけではありません。

使うべきケースは、同じファイル内で何度もそのnamespaceの型を使う場合です。

C#
using System.Collections.Generic;

List<string> names = new List<string>();
Dictionary<int, string> users = new Dictionary<int, string>();

このように、ListDictionaryを何度も使うならusingを書くとコードが読みやすくなります。

一方、1回しか使わない型で、完全修飾名でも意味が明確な場合は、usingを書かなくてもよいことがあります。

C#
System.IO.File.WriteAllText("sample.txt", "Hello");

また、同じ名前のクラスが複数存在する場合、usingを追加しすぎるとあいまいなエラーが出ることがあります。

C#
using MyApp.ViewModels;
using MyApp.Entities;

User user = new User(); // どちらのUserかわからない

このような場合は、完全修飾名を使うと安全です。

C#
MyApp.Entities.User user = new MyApp.Entities.User();

または、usingエイリアスを使います。

C#
using EntityUser = MyApp.Entities.User;
using ViewUser = MyApp.ViewModels.User;

EntityUser user = new EntityUser();

usingはコードを短くするために便利ですが、読みやすさを損なわないように使うことが大切です。

3-5. using static・usingエイリアス・global usingの違い

C#には通常のusing以外にも、いくつかの便利な書き方があります。

using staticは、静的メンバーをクラス名なしで呼び出せるようにする書き方です。

C#
using static System.Console;

WriteLine("Hello");

通常は次のように書きます。

C#
Console.WriteLine("Hello");

using static System.Console;を書くと、Console.を省略できます。

ただし、使いすぎると、どのクラスのメソッドを呼んでいるのかわかりにくくなる場合があります。

usingエイリアスは、型や名前空間に別名を付ける機能です。

C#
using TextList = System.Collections.Generic.List<string>;

TextList names = new TextList();

同じクラス名が複数ある場合にも便利です。

C#
using ViewUser = MyApp.ViewModels.User;
using EntityUser = MyApp.Entities.User;

ViewUser viewUser = new ViewUser();
EntityUser entityUser = new EntityUser();

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

C#
global using System;
global using System.Collections.Generic;

通常のusingは、そのファイル内だけで有効です。

C#
using System;

一方、global usingはプロジェクト全体で有効になります。そのため、よく使うnamespaceを毎回書かずに済みます。

.NET 6以降のプロジェクトでは、暗黙的にいくつかのglobal usingが有効になっている場合があります。そのため、using System;を書いていなくてもConsoleが使えることがあります。

ただし、初心者のうちは「なぜusingを書いていないのに使えるのか」と混乱しやすいポイントです。プロジェクト設定によって、暗黙的なusingが有効になっている場合があると覚えておきましょう。

4. C# namespaceの具体的な使い方

4-1. 自作クラスをnamespaceに分けて管理する

実際に、自作クラスをnamespaceで分けてみましょう。

たとえば、ユーザー情報を表すUserクラスを作成します。

C#
namespace MyApp.Models;

public class User
{
public string Name { get; set; } = "";
public int Age { get; set; }
}

次に、ユーザーに関する処理を行うUserServiceクラスを作成します。

C#
namespace MyApp.Services;

using MyApp.Models;

public class UserService
{
public void PrintUser(User user)
{
Console.WriteLine($"{user.Name}さんは{user.Age}歳です。");
}
}

UserクラスはMyApp.Modelsにあり、UserServiceクラスはMyApp.Servicesにあります。

そのため、UserService側では次のusingを書いています。

C#
using MyApp.Models;

これにより、MyApp.Models.Userを短くUserと書けます。

さらに、Program.csから呼び出す場合は次のようになります。

C#
using MyApp.Models;
using MyApp.Services;

User user = new User
{
Name = "Taro",
Age = 20
};

UserService service = new UserService();
service.PrintUser(user);

namespaceを分けることで、データを表すクラスと処理を担当するクラスを整理できます。

4-2. 別ファイルのクラスをnamespace経由で呼び出す

C#では、別ファイルにあるクラスでも、同じプロジェクト内に含まれていれば利用できます。

たとえば、次のようなファイル構成を考えます。

MyApp
├─ Program.cs
├─ Models
│ └─ User.cs
└─ Services
└─ UserService.cs

Models/User.csは次のようにします。

C#
namespace MyApp.Models;

public class User
{
public string Name { get; set; } = "";
}

Services/UserService.csは次のようにします。

C#
namespace MyApp.Services;

using MyApp.Models;

public class UserService
{
public void Print(User user)
{
Console.WriteLine(user.Name);
}
}

Program.csでは、次のようにusingを書きます。

C#
using MyApp.Models;
using MyApp.Services;

User user = new User
{
Name = "Hanako"
};

UserService service = new UserService();
service.Print(user);

ここで重要なのは、ファイルが分かれていても、namespaceusingによってクラスを参照できるという点です。

C#では、同じプロジェクトに含まれているソースファイルは一緒にコンパイルされます。そのため、別ファイルにあるクラスでも、適切なnamespaceを指定すれば利用できます。

4-3. フォルダ構成とnamespace名の関係

C#では、フォルダ構成とnamespace名を一致させることがよくあります。

たとえば、次のフォルダ構成があるとします。

MyApp
├─ Models
│ └─ User.cs
├─ Services
│ └─ UserService.cs
└─ Repositories
└─ UserRepository.cs

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

C#
namespace MyApp.Models;

public class User
{
}
C#
namespace MyApp.Services;

public class UserService
{
}
C#
namespace MyApp.Repositories;

public class UserRepository
{
}

フォルダ名とnamespace名をそろえると、ファイルの場所とコード上の分類が一致するため、探しやすくなります。

ただし、C#のルールとして、フォルダ名とnamespace名が必ず一致していなければならないわけではありません。

たとえば、Modelsフォルダにあるファイルで、次のようなnamespaceを書くことも技術的には可能です。

C#
namespace MyApp.Data;

public class User
{
}

この場合でも、構文としては間違いではありません。

しかし、フォルダ名とnamespace名が違うと、他の開発者が混乱しやすくなります。特別な理由がなければ、フォルダ構成とnamespace名は対応させるのがおすすめです。

4-4. 複数のnamespaceを使い分ける例

アプリケーションが少し大きくなると、複数のnamespaceを使い分けることになります。

たとえば、ユーザー登録機能を考えてみます。

MyApp
├─ Models
│ └─ User.cs
├─ Services
│ └─ UserService.cs
├─ Repositories
│ └─ UserRepository.cs
└─ Validators
└─ UserValidator.cs

Userクラスです。

C#
namespace MyApp.Models;

public class User
{
public string Name { get; set; } = "";
public string Email { get; set; } = "";
}

入力チェック用のUserValidatorクラスです。

C#
namespace MyApp.Validators;

using MyApp.Models;

public class UserValidator
{
public bool IsValid(User user)
{
return !string.IsNullOrWhiteSpace(user.Name)
&& !string.IsNullOrWhiteSpace(user.Email);
}
}

データ保存用のUserRepositoryクラスです。

C#
namespace MyApp.Repositories;

using MyApp.Models;

public class UserRepository
{
public void Save(User user)
{
Console.WriteLine($"{user.Name}を保存しました。");
}
}

処理全体をまとめるUserServiceクラスです。

C#
namespace MyApp.Services;

using MyApp.Models;
using MyApp.Repositories;
using MyApp.Validators;

public class UserService
{
private readonly UserValidator _validator = new UserValidator();
private readonly UserRepository _repository = new UserRepository();

public void Register(User user)
{
if (!_validator.IsValid(user))
{
Console.WriteLine("ユーザー情報が不正です。");
return;
}

_repository.Save(user);
}
}

このように、役割ごとにnamespaceを分けると、各クラスの責任が明確になります。

4-5. ConsoleやListで見る標準ライブラリのnamespace

C#でよく使う標準ライブラリにも、namespaceがあります。

たとえば、ConsoleSystem名前空間にあります。

C#
System.Console.WriteLine("Hello");

通常は、次のようにusing System;を書くことで短く書けます。

C#
using System;

Console.WriteLine("Hello");

List<T>System.Collections.Generic名前空間にあります。

C#
using System.Collections.Generic;

List<string> names = new List<string>();
names.Add("Taro");
names.Add("Hanako");

FileSystem.IO名前空間にあります。

C#
using System.IO;

File.WriteAllText("sample.txt", "Hello");

TaskSystem.Threading.Tasks名前空間にあります。

C#
using System.Threading.Tasks;

Task task = Task.Run(() =>
{
Console.WriteLine("処理中");
});

このように、標準ライブラリの型もそれぞれのnamespaceに分類されています。

エラーで「型または名前空間の名前が見つかりません」と表示された場合は、その型がどのnamespaceに属しているかを確認し、必要なusingを追加することが大切です。

5. namespaceでよくあるエラーと対処法

5-1. 「型または名前空間の名前が見つかりません」の原因

C#でよく見るエラーの1つが、次のようなエラーです。

型または名前空間の名前 'User' が見つかりませんでした

このエラーは、C#が指定された型やnamespaceを見つけられないときに発生します。

よくある原因は次のとおりです。

まず、usingが不足しているケースです。

C#
User user = new User();

UserクラスがMyApp.Models名前空間にある場合、次のusingが必要です。

C#
using MyApp.Models;

User user = new User();

または完全修飾名で書きます。

C#
MyApp.Models.User user = new MyApp.Models.User();

次に、namespace名を間違えているケースです。

C#
using MyApp.Model; // 誤り

実際のnamespaceMyApp.Modelsなら、正しくは次のように書きます。

C#
using MyApp.Models;

また、クラス名のスペルミスでも同じようなエラーが出ます。

C#
Usre user = new Usre(); // 誤り

正しくは次のようにします。

C#
User user = new User();

エラーが出た場合は、usingnamespace名、クラス名、プロジェクト参照を順番に確認しましょう。

5-2. usingを書いても認識されない場合の確認ポイント

usingを書いたのに型が認識されない場合は、いくつか確認すべきポイントがあります。

まず、namespace名が正しいか確認します。

C#
namespace MyApp.Models;

public class User
{
}

この場合、使う側では次のように書く必要があります。

C#
using MyApp.Models;

MyApp.ModelMyApp.Modelesのように少しでも違うと認識されません。

次に、クラスのアクセス修飾子を確認します。

C#
class User
{
}

このようにpublicが付いていない場合、別のプロジェクトから参照できないことがあります。

外部から使いたい場合は、次のようにpublicを付けます。

C#
public class User
{
}

同じプロジェクト内であれば使える場合もありますが、別プロジェクトから参照する場合はpublicが必要です。

さらに、別プロジェクトのクラスを使っている場合は、プロジェクト参照が追加されているか確認します。

たとえば、MyApp.WebプロジェクトからMyApp.Coreプロジェクトのクラスを使う場合、MyApp.WebからMyApp.Coreへの参照が必要です。

usingは参照を追加する機能ではありません。usingを書いても、プロジェクト自体が参照されていなければ型は見つかりません。

5-3. namespace名とフォルダ名が違うとエラーになる?

C#では、namespace名とフォルダ名が違っていても、それだけでエラーにはなりません。

たとえば、Modelsフォルダの中にあるUser.csで、次のように書いてもコンパイルは可能です。

C#
namespace MyApp.Entities;

public class User
{
}

フォルダ名はModelsですが、namespaceMyApp.Entitiesです。

これはC#の文法としては問題ありません。

ただし、使う側では実際のnamespaceに合わせる必要があります。

C#
using MyApp.Entities;

User user = new User();

フォルダ名を見て、次のように書くとエラーになります。

C#
using MyApp.Models; // 実際のnamespaceと違う

つまり、C#が参照するのはフォルダ名ではなく、コードに書かれたnamespace名です。

ただし、フォルダ名とnamespace名がずれていると、人間が混乱しやすくなります。特別な理由がなければ、フォルダ構成とnamespaceは一致させるのがよいでしょう。

5-4. クラス名が重複してあいまいになるエラー

複数のnamespaceに同じクラス名がある場合、あいまいな参照エラーが発生することがあります。

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

C#
namespace MyApp.ViewModels;

public class User
{
}
C#
namespace MyApp.Entities;

public class User
{
}

使う側で両方のnamespaceusingすると、問題が起きます。

C#
using MyApp.ViewModels;
using MyApp.Entities;

User user = new User();

この場合、C#はUserMyApp.ViewModels.UserなのかMyApp.Entities.Userなのか判断できません。

対処法の1つは、完全修飾名を使うことです。

C#
MyApp.Entities.User user = new MyApp.Entities.User();

もう1つは、usingエイリアスを使うことです。

C#
using ViewUser = MyApp.ViewModels.User;
using EntityUser = MyApp.Entities.User;

ViewUser viewUser = new ViewUser();
EntityUser entityUser = new EntityUser();

同じクラス名を使うこと自体は問題ありませんが、同じファイル内で両方を扱う場合は、区別できるように書く必要があります。

5-5. ファイルスコープnamespaceで起きやすい書き方ミス

ファイルスコープ形式のnamespaceでは、セミコロン;を使います。

正しい書き方は次のとおりです。

C#
namespace MyApp.Models;

public class User
{
}

よくあるミスは、ブロックスコープ形式と混ぜてしまうことです。

C#
namespace MyApp.Models;

{
public class User
{
}
}

これは誤りです。ファイルスコープ形式では、namespaceのための波かっこは不要です。

逆に、ブロックスコープ形式では波かっこが必要です。

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

また、1つのファイルでファイルスコープ形式のnamespaceを複数書くことはできません。

C#
namespace MyApp.Models;

public class User
{
}

namespace MyApp.Services; // 誤り

public class UserService
{
}

複数のnamespaceを1つのファイルに書きたい場合は、ブロックスコープ形式を使います。

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

namespace MyApp.Services
{
public class UserService
{
}
}

ファイルスコープ形式は便利ですが、「1ファイルにつき基本的に1つのnamespace」と考えるとわかりやすいです。

5-6. 外部ライブラリのnamespaceが見つからない場合

NuGetなどで外部ライブラリを使うときにも、namespace関連のエラーが出ることがあります。

たとえば、外部ライブラリの型を使おうとして次のエラーが出る場合があります。

型または名前空間の名前 'JsonConvert' が見つかりませんでした

この場合、主な原因は次の3つです。

1つ目は、ライブラリがインストールされていないことです。

NuGetパッケージが必要な場合は、まずパッケージを追加する必要があります。

2つ目は、usingが不足していることです。

たとえば、JsonConvertを使う場合、ライブラリによっては次のようなusingが必要です。

C#
using Newtonsoft.Json;

3つ目は、プロジェクト参照やパッケージ参照が正しくないことです。

usingを書くだけでは、外部ライブラリを使えるようにはなりません。まずプロジェクトにライブラリが追加されている必要があります。

つまり、外部ライブラリのnamespaceが見つからない場合は、次の順番で確認します。

  • NuGetパッケージがインストールされているか

  • 正しいusingを書いているか

  • 型名やnamespace名を間違えていないか

  • 対象プロジェクトに参照が追加されているか

usingは「すでに参照できる型を短く書くためのもの」であり、ライブラリをインストールする機能ではない点に注意しましょう。

6. namespace設計のベストプラクティス

6-1. プロジェクト名を基準にnamespaceを決める

C#のnamespaceは、プロジェクト名を基準に決めるのが一般的です。

たとえば、プロジェクト名がSampleAppなら、基本のnamespaceも次のようにします。

C#
namespace SampleApp;

その下に、機能や役割ごとの名前を追加します。

C#
namespace SampleApp.Models;
namespace SampleApp.Services;
namespace SampleApp.Repositories;
namespace SampleApp.Controllers;

このようにしておくと、どのアプリケーションに属するコードなのかが明確になります。

会社や組織の名前を含める場合もあります。

C#
namespace CompanyName.SampleApp.Models;

ライブラリを作成する場合は、他のライブラリと名前が衝突しないように、会社名や製品名を含めることが多いです。

C#
namespace Contoso.Logging;
namespace Contoso.Logging.Formatters;
namespace Contoso.Logging.Providers;

個人開発や小規模アプリでは、まずはプロジェクト名をルートnamespaceにするだけでも十分です。

6-2. 機能ごとにnamespaceを分ける

namespaceは、機能や役割ごとに分けると管理しやすくなります。

よくある分け方は、役割別の分類です。

C#
namespace MyApp.Models;
namespace MyApp.Services;
namespace MyApp.Repositories;
namespace MyApp.Controllers;
namespace MyApp.Validators;

この分け方では、「何をするクラスか」によって分類します。

一方、機能別に分ける方法もあります。

C#
namespace MyApp.Features.Users;
namespace MyApp.Features.Products;
namespace MyApp.Features.Orders;

さらに、その中で役割を分けることもあります。

C#
namespace MyApp.Features.Users.Models;
namespace MyApp.Features.Users.Services;
namespace MyApp.Features.Users.Repositories;

どちらが正解というわけではありません。

小さなアプリでは役割別に分けるとシンプルです。

C#
MyApp.Models
MyApp.Services
MyApp.Repositories

機能が多い大きなアプリでは、機能別に分けた方が管理しやすいことがあります。

C#
MyApp.Features.Users
MyApp.Features.Products
MyApp.Features.Orders

大切なのは、プロジェクト全体で一貫したルールにすることです。

6-3. 深すぎるnamespace階層は避ける

namespaceはドットで階層化できますが、深くしすぎると読みにくくなります。

たとえば、次のようなnamespaceは長すぎます。

C#
namespace MyApp.Features.Users.Profile.Settings.Validation.Rules.Email;

完全修飾名で書くと、さらに長くなります。

C#
MyApp.Features.Users.Profile.Settings.Validation.Rules.Email.EmailRule rule =
new MyApp.Features.Users.Profile.Settings.Validation.Rules.Email.EmailRule();

これではコードが読みづらくなります。

適度に短くすると、扱いやすくなります。

C#
namespace MyApp.Users.Validation;

または、機能ごとにまとめます。

C#
namespace MyApp.Features.Users.Validation;

深い階層が必要になる場合もありますが、初心者のうちは次のようなシンプルな構成から始めるとよいです。

C#
MyApp.Models
MyApp.Services
MyApp.Repositories
MyApp.Controllers

プロジェクトが大きくなってから、必要に応じて細かく分ければ十分です。

6-4. クラス名とnamespace名の衝突に注意する

namespace名とクラス名が同じになると、コードがわかりにくくなることがあります。

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

C#
namespace MyApp.User;

public class User
{
}

この場合、MyApp.User.Userという名前になります。

C#
MyApp.User.User user = new MyApp.User.User();

文法上は可能ですが、読みやすいとは言えません。

このような場合は、namespaceを複数形にすることがあります。

C#
namespace MyApp.Users;

public class User
{
}

すると、完全修飾名は次のようになります。

C#
MyApp.Users.User user = new MyApp.Users.User();

こちらの方が自然です。

また、namespace名には機能名やカテゴリ名を使い、クラス名には具体的な型名を使うとわかりやすくなります。

C#
namespace MyApp.Authentication;

public class LoginService
{
}
C#
namespace MyApp.Notifications;

public class EmailSender
{
}

名前の衝突や読みにくさを避けるために、namespace名とクラス名の関係にも注意しましょう。

6-5. チーム開発でnamespaceルールを統一する

チーム開発では、namespaceのルールを統一することが重要です。

人によって書き方が違うと、プロジェクト全体の見通しが悪くなります。

たとえば、同じユーザー関連のクラスなのに、次のようにバラバラだと混乱します。

C#
namespace MyApp.User;
namespace MyApp.Users;
namespace MyApp.Features.User;
namespace MyApp.Feature.Users;

このような状態になると、クラスを探すのに時間がかかります。

チームでは、次のようなルールを決めておくとよいです。

  • ルートnamespaceはプロジェクト名にする

  • フォルダ構成とnamespaceをそろえる

  • 機能別に分けるか、役割別に分けるかを決める

  • namespace名は単数形か複数形かを統一する

  • 略語を使うかどうかを決める

たとえば、役割別に分けるルールなら次のようにします。

C#
MyApp.Models
MyApp.Services
MyApp.Repositories
MyApp.Controllers

機能別に分けるルールなら次のようにします。

C#
MyApp.Features.Users
MyApp.Features.Products
MyApp.Features.Orders

どちらを選ぶ場合でも、プロジェクト内で一貫していることが大切です。

7. 初心者が混乱しやすいnamespaceの疑問

7-1. namespaceは必ず書く必要がある?

C#では、namespaceを必ず書かなければならないわけではありません。

次のように、namespaceなしでもクラスを定義できます。

C#
public class User
{
}

この場合、Userクラスはグローバル名前空間に属します。

また、簡単なコンソールアプリでは、トップレベルステートメントを使って次のように書くこともあります。

C#
Console.WriteLine("Hello");

このような短いサンプルでは、namespaceが見えないことがあります。

しかし、実際のアプリケーションでは、namespaceを書くのが一般的です。

理由は、クラスを整理しやすくなり、名前の衝突を防げるからです。

初心者の学習段階では、短いコードでnamespaceを省略しても問題ありません。ただし、複数のファイルやクラスを扱うようになったら、namespaceを使う習慣をつけるとよいでしょう。

7-2. 1つのファイルに複数のnamespaceを書ける?

C#では、1つのファイルに複数のnamespaceを書くことができます。

ただし、複数のnamespaceを書く場合は、ブロックスコープ形式を使います。

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

namespace MyApp.Services
{
public class UserService
{
}
}

このように、1つのファイル内に複数のnamespaceを定義できます。

ただし、実務では、1つのファイルに複数のnamespaceを書くことはあまり多くありません。

通常は、1つのファイルに1つの主要なクラスを書き、そのファイルに対応するnamespaceを1つ書きます。

C#
namespace MyApp.Models;

public class User
{
}

ファイルスコープ形式のnamespaceを使う場合は、1つのファイルに複数のファイルスコープnamespaceを書くことはできません。

C#
namespace MyApp.Models;

public class User
{
}

namespace MyApp.Services; // 誤り

public class UserService
{
}

複数のnamespaceを1ファイルに書く必要がある場合は、ブロックスコープ形式を使いましょう。

7-3. namespaceの名前は自由に決めていい?

namespaceの名前は、基本的には自由に決められます。

たとえば、次のような名前を付けることができます。

C#
namespace MyApp;
namespace MyApp.Models;
namespace Sample.Project.Services;

ただし、自由に決められるからといって、何でもよいわけではありません。

わかりにくい名前は避けるべきです。

C#
namespace A;
namespace Test1;
namespace MyNamespace;

学習用なら問題ない場合もありますが、実務では意味のある名前にすることが大切です。

おすすめは、プロジェクト名を基準にすることです。

C#
namespace ShoppingApp.Products;
namespace ShoppingApp.Orders;
namespace ShoppingApp.Users;

また、C#の予約語はそのままでは使えません。

たとえば、classnamespaceのようなキーワードは名前として使わないようにします。

どうしても使いたい場合は@を付ける方法もありますが、通常は避けるべきです。

C#
namespace MyApp.@class;

このような書き方は読みにくいため、別の名前にするのが無難です。

7-4. namespaceとフォルダ構成は一致させるべき?

namespaceとフォルダ構成は、必ず一致させる必要はありません。

しかし、基本的には一致させることをおすすめします。

たとえば、次のフォルダ構成があるとします。

MyApp
├─ Models
│ └─ User.cs
└─ Services
└─ UserService.cs

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

C#
namespace MyApp.Models;

public class User
{
}
C#
namespace MyApp.Services;

public class UserService
{
}

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

一方、次のようにずれていると混乱します。

Models/User.cs
C#
namespace MyApp.Entities;

public class User
{
}

C#としてはエラーではありませんが、ファイルの場所からnamespaceを予想しにくくなります。

そのため、特別な理由がない限り、フォルダ構成とnamespaceはそろえるのがベストです。

7-5. Visual Studioが自動生成するnamespaceは変更していい?

Visual Studioでクラスを追加すると、プロジェクト名やフォルダ名に基づいてnamespaceが自動生成されることがあります。

たとえば、プロジェクト名がMyAppで、ModelsフォルダにUser.csを追加すると、次のようなnamespaceになることがあります。

C#
namespace MyApp.Models;

public class User
{
}

この自動生成されたnamespaceは変更できます。

ただし、変更する場合は、他のファイルから参照しているusingも合わせて変更する必要があります。

たとえば、namespaceを次のように変更したとします。

C#
namespace MyApp.Entities;

public class User
{
}

その場合、使う側では次のように変更します。

C#
using MyApp.Entities;

以前のままではエラーになります。

C#
using MyApp.Models; // 変更後は使えない

Visual Studioが自動生成するnamespaceは、多くの場合、プロジェクト構成に合った自然な名前になっています。初心者のうちは、特別な理由がなければそのまま使うのがおすすめです。

8. C# namespaceの理解を深める実践例

8-1. namespaceなしのコードをnamespaceありに変更する

まず、namespaceなしのコードを見てみましょう。

C#
public class User
{
public string Name { get; set; } = "";
}

public class Program
{
public static void Main()
{
User user = new User();
user.Name = "Taro";

Console.WriteLine(user.Name);
}
}

このコードは小さなサンプルとしては問題ありません。

しかし、実際のアプリケーションでは、クラスを整理するためにnamespaceを付けた方がよいです。

UserクラスをMyApp.Modelsに入れます。

C#
namespace MyApp.Models;

public class User
{
public string Name { get; set; } = "";
}

Program側では、using MyApp.Models;を追加します。

C#
using MyApp.Models;

namespace MyApp;

public class Program
{
public static void Main()
{
User user = new User();
user.Name = "Taro";

Console.WriteLine(user.Name);
}
}

これで、UserクラスがMyApp.Modelsに整理されました。

さらに、完全修飾名で書くこともできます。

C#
namespace MyApp;

public class Program
{
public static void Main()
{
MyApp.Models.User user = new MyApp.Models.User();
user.Name = "Taro";

Console.WriteLine(user.Name);
}
}

ただし、毎回MyApp.Models.Userと書くのは長いため、通常はusingを使います。

8-2. 同じクラス名を別namespaceで使い分ける

次に、同じUserという名前のクラスを別々のnamespaceで使い分ける例です。

画面表示用のUserクラスを作ります。

C#
namespace MyApp.ViewModels;

public class User
{
public string DisplayName { get; set; } = "";
}

データ保存用のUserクラスを作ります。

C#
namespace MyApp.Entities;

public class User
{
public string Name { get; set; } = "";
public string Email { get; set; } = "";
}

同じUserという名前ですが、namespaceが違うため別の型として扱われます。

使う側では、完全修飾名で区別できます。

C#
MyApp.ViewModels.User viewUser = new MyApp.ViewModels.User();
viewUser.DisplayName = "Taro";

MyApp.Entities.User entityUser = new MyApp.Entities.User();
entityUser.Name = "Taro";
entityUser.Email = "taro@example.com";

ただし、完全修飾名を毎回書くと長いため、usingエイリアスを使うと読みやすくなります。

C#
using ViewUser = MyApp.ViewModels.User;
using EntityUser = MyApp.Entities.User;

ViewUser viewUser = new ViewUser();
viewUser.DisplayName = "Taro";

EntityUser entityUser = new EntityUser();
entityUser.Name = "Taro";
entityUser.Email = "taro@example.com";

このように、namespaceを使うことで同じクラス名でも安全に使い分けられます。

8-3. usingを使ってコードを短く書く

usingを使わない場合、コードは次のように長くなります。

C#
public class Program
{
public static void Main()
{
System.Collections.Generic.List<string> names =
new System.Collections.Generic.List<string>();

names.Add("Taro");
names.Add("Hanako");

System.Console.WriteLine(names.Count);
}
}

このコードでは、List<string>Consoleを完全修飾名で書いています。

usingを使うと、次のように短くできます。

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

public class Program
{
public static void Main()
{
List<string> names = new List<string>();

names.Add("Taro");
names.Add("Hanako");

Console.WriteLine(names.Count);
}
}

さらに、自作クラスでも同じです。

C#
using MyApp.Models;

User user = new User();

usingがない場合は、次のように書く必要があります。

C#
MyApp.Models.User user = new MyApp.Models.User();

usingは、コードを短く読みやすくするための便利な仕組みです。

ただし、同じ名前の型が複数ある場合は注意が必要です。

C#
using MyApp.ViewModels;
using MyApp.Entities;

User user = new User(); // あいまい

このような場合は、完全修飾名やusingエイリアスを使いましょう。

8-4. エラーが出るコードと修正後のコードを比較する

最後に、namespace関連でよくあるエラーを、修正前と修正後で比較します。

まず、Userクラスがあります。

C#
namespace MyApp.Models;

public class User
{
public string Name { get; set; } = "";
}

使う側で次のように書くと、エラーになります。

C#
namespace MyApp;

public class Program
{
public static void Main()
{
User user = new User();
user.Name = "Taro";

Console.WriteLine(user.Name);
}
}

UserクラスはMyApp.Models名前空間にあるため、Program側からはそのままでは見つけられません。

修正方法は、using MyApp.Models;を追加することです。

C#
using MyApp.Models;

namespace MyApp;

public class Program
{
public static void Main()
{
User user = new User();
user.Name = "Taro";

Console.WriteLine(user.Name);
}
}

または、完全修飾名で書きます。

C#
namespace MyApp;

public class Program
{
public static void Main()
{
MyApp.Models.User user = new MyApp.Models.User();
user.Name = "Taro";

Console.WriteLine(user.Name);
}
}

次に、namespace名を間違えた例です。

C#
using MyApp.Model; // 誤り

namespace MyApp;

public class Program
{
public static void Main()
{
User user = new User();
}
}

実際のnamespaceMyApp.Modelsなら、正しくは次のようにします。

C#
using MyApp.Models;

namespace MyApp;

public class Program
{
public static void Main()
{
User user = new User();
}
}

さらに、クラスがpublicでないために別プロジェクトから使えない例です。

C#
namespace MyApp.Models;

class User
{
}

別プロジェクトから使う場合は、次のようにpublicを付けます。

C#
namespace MyApp.Models;

public class User
{
}

namespace関連のエラーが出たときは、次の順番で確認すると解決しやすくなります。

  1. クラス名のスペルは正しいか

  2. namespace名は正しいか

  3. 必要なusingを書いているか

  4. 別プロジェクトの場合、プロジェクト参照があるか

  5. クラスに必要なアクセス修飾子が付いているか

  6. 同じ名前の型が複数あってあいまいになっていないか

まとめ

C#のnamespaceは、クラスや型を整理し、名前の衝突を防ぐための重要な仕組みです。

小さなプログラムでは意識しなくても動くことがありますが、複数のファイルやクラスを扱うようになると、namespaceの理解は欠かせません。

namespaceは、クラスを分類するための名前の箱です。

C#
namespace MyApp.Models;

public class User
{
}

一方、usingは、他のnamespaceにある型を短く書けるようにするためのものです。

C#
using MyApp.Models;

User user = new User();

usingを書かない場合は、完全修飾名で指定できます。

C#
MyApp.Models.User user = new MyApp.Models.User();

また、同じクラス名が複数ある場合でも、namespaceを分ければ安全に使い分けられます。

C#
MyApp.ViewModels.User viewUser = new MyApp.ViewModels.User();
MyApp.Entities.User entityUser = new MyApp.Entities.User();

namespaceを設計するときは、プロジェクト名を基準にし、フォルダ構成と対応させるとわかりやすくなります。

C#
namespace MyApp.Models;
namespace MyApp.Services;
namespace MyApp.Repositories;

初心者がまず押さえるべきポイントは、次の5つです。

  • namespaceは型を整理するための名前

  • usingは型を短く書くための指定

  • namespaceが違えば同じクラス名でも区別できる

  • フォルダ名とnamespace名は一致させると管理しやすい

  • エラーが出たらusing、namespace名、クラス名、参照設定を確認する

C#のnamespaceを正しく理解すると、コードの構成がわかりやすくなり、エラーにも対応しやすくなります。最初は自動生成されたnamespaceを見ながら、少しずつ自分で整理できるようにしていきましょう。