C#: 名前空間とusing
1. 名前空間とは何か
名前空間とは、コードを整理し、型名の競合を回避するために用いられる論理的なグループ化の仕組みです。大規模なプロジェクトでは、異なるモジュール間で同じ名前のクラスが定義される場合がありますが、名前空間は型に対して修飾されたパスを提供します。
2. 名前空間の定義
namespaceというキーワードを使用して名前空間を宣言し、型は中括弧内に記述します。
▶ サンプル
namespace MyApp.Models
{
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
}
namespace MyApp.Services
{
public class UserService
{
public string GetInfo()
{
return "UserService is ready";
}
}
}
3. 名前空間のネスト
名前空間はネストすることができ、その場合、内側の名前空間は外側の名前空間のサブスペースとなります。ドット表記によるアクセスは、このネスト構造と同等です。
▶ サンプル
namespace Company
{
namespace Products
{
namespace Electronics
{
public class Phone
{
public string Model { get; set; }
}
}
}
}
namespace Company.Products.Electronics
{
public class Tablet
{
public string Model { get; set; }
}
}
Company.Products.Electronics.PhoneとCompany.Products.Electronics.Tabletは同じ名前空間に属しています。
4. ファイルスコープのネームスペース (C# 10)
C# 10 では、末尾にセミコロンを付けるファイルスコープのネームスペースが導入されました。ファイル全体が自動的にそのネームスペースに属するため、ネストされたインデントが軽減されます。
▶ サンプル
namespace MyApp.Services;
public class EmailService
{
public void Send(string to)
{
System.Console.WriteLine($"Sending email to {to}");
}
}
Sending email to user@example.com
5. using ディレクティブ
usingディレクティブは名前空間をインポートするため、完全修飾名を記述することなく、その型を直接使用することができます。
▶ サンプル
using System;
namespace MyApp
{
class Program
{
static void Main()
{
Console.WriteLine("No need for System.Console");
Console.WriteLine(DateTime.Now.Year);
}
}
}
No need for System.Console
2026
6. エイリアスの使用
名前空間が長すぎる場合や、型名の競合がある場合は、using ... = ...を使用してエイリアスを作成できます。
▶ サンプル
using Dict = System.Collections.Generic.Dictionary`<string, int>`;
using StringBuilder = System.Text.StringBuilder;
namespace MyApp
{
class Program
{
static void Main()
{
Dict scores = new Dict();
scores.Add("Alice", 95);
scores.Add("Bob", 87);
StringBuilder sb = new StringBuilder();
foreach (var pair in scores)
{
sb.AppendLine($"{pair.Key}: {pair.Value}");
}
System.Console.WriteLine(sb.ToString());
}
}
}
Alice: 95
Bob: 87
7. static の使用(C# 6)
using staticは、型の静的メンバーをインポートし、型名を指定せずにそれらを呼び出せるようにします。
▶ サンプル
using static System.Console;
using static System.Math;
namespace MyApp
{
class Program
{
static void Main()
{
WriteLine($"PI = {PI}");
WriteLine($"Max = {Max(10, 20)}");
WriteLine($"Sqrt(144) = {Sqrt(144)}");
}
}
}
PI = 3.14159265358979
Max = 20
Sqrt(144) = 12
8. グローバル変数の使用(C# 10)
1つのファイルでglobal usingを宣言すると、その名前空間がプロジェクト全体のすべてのファイルで利用可能になり、usingを繰り返し記述する必要がなくなります。
▶ サンプル
global using System;
global using System.Collections.Generic;
global using System.Linq;
グローバルな「using」文をGlobalUsings.csファイルにまとめて記述し、一元管理を行うのが一般的な慣行です。
9. 暗黙的な Usings 宣言 (C# 10)
プロジェクトファイルで<ImplicitUsings>enable</ImplicitUsings>を有効にすると、SDKスタイルのプロジェクトにおいて、よく使用される名前空間に対するグローバルなusing文が自動的に追加されます。
▶ サンプル
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
コンソールプロジェクトには、自動的に以下の名前空間が含まれます:System、System.Collections.Generic、System.IO、System.Linq、System.Threading、System.Threading.Tasksなど。
10. using および IDisposable
usingステートメントは、IDisposableオブジェクトが使用後にリソースを適切に解放することを保証します。C# 8 では、using 宣言構文もサポートされています。
▶ サンプル
using System;
using System.IO;
namespace MyApp
{
class Program
{
static void Main()
{
using (var fs = new FileStream("test.txt", FileMode.Create))
{
byte[] data = System.Text.Encoding.UTF8.GetBytes("Hello");
fs.Write(data, 0, data.Length);
}
using var reader = new StreamReader("test.txt");
Console.WriteLine(reader.ReadToEnd());
}
}
}
Hello
中括弧形式は、そのスコープの終了時に解放されます。一方、using varは、それを囲むスコープの終了時に解放されます。
11. .NET クラスライブラリのネームスペース構成
.NET クラスライブラリでは、機能が System ネームスペースの下のサブネームスペースに整理されています。
▶ サンプル
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MyApp
{
class Program
{
static void Main()
{
ArrayList list = new ArrayList { 1, 2, 3 };
List````<string>```` names = new List````<string>```` { "Alice", "Bob" };
var upper = names.Select(n => n.ToUpper());
StringBuilder sb = new StringBuilder("Count: ");
sb.Append(names.Count);
Console.WriteLine(sb.ToString());
}
}
}
Count: 2
| 名前空間 | 目的 |
|---|---|
System |
基本型(Console、DateTime、Math など) |
System.IO |
ファイルおよびストリームの操作 |
System.Collections |
汎用ではないコレクション(ArrayList、Hashtable) |
System.Collections.Generic |
汎用コレクション(リスト<T>、辞書<K,V\>) |
System.Linq |
LINQ クエリ拡張 |
System.Text |
文字列処理(StringBuilder、エンコーディング) |
System.Threading |
スレッドと同期 |
System.Threading.Tasks |
非同期プログラミング(Task、Task<T>) |
❓ よくある質問
📖 まとめ
- 名前空間は
namespaceで定義され、中括弧のネストやドット表記に対応しています usingディレクティブは名前空間をインポートし、完全修飾名を排除しますusing Alias = FullTypeNameは、名前の競合を解決したり、長い名前を簡略化したりしますusing staticは、直接呼び出しを行うために型の静的メンバーをインポートしますglobal usingはプロジェクト全体に適用されるため、各ファイルでの重複を回避できます- ファイルスコープのネームスペース
namespace X;により、インデントレベルが減少する - 暗黙的な「using」文では、プロジェクトの設定を通じて一般的な名前空間が自動的に含められます
usingstatements/declarations は、IDisposable リソースの解放を行うためのものです- .NET クラスライブラリは、機能ごとに System サブネームスペースに分類されています
📝 練習問題
- 2階層のネストされた名前空間
School.Teachers内にTeacherクラスを作成し、Main内でそのインスタンスを作成する usingというエイリアスを使用して、System.Collections.Generic.List``<string>の短縮エイリアスを作成し、それを使ってリストを作成し、要素を追加し、それらを出力するusing static System.Mathを使用して、Sqrt、Abs、およびRoundを直接呼び出し、結果を出力するSystem、System.IO、およびSystem.Linqのglobal using宣言を含むGlobalUsings.csファイルを作成し、別のファイルでこれらのusing文を省略して、正常に動作することを確認する- 中括弧
usingを使った文とusing varを使った宣言の両方の方法を用いて、StreamWriterでファイルに書き込み、その違いを確認する