C#のusingとは?ディレクティブ・ステートメント・static・global usingの違いと使い方を初心者向けに解説
はじめに
C#のusingは、初心者がつまずきやすいキーワードのひとつです。理由は、同じusingという単語が、場面によってまったく違う意味で使われるからです。
たとえば、次の2つはどちらもusingですが、役割は別物です。
C#using System;
Console.WriteLine("Hello");
C#using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
1つ目のusing System;は、System名前空間にある型を短く書くためのものです。2つ目のusing (...)は、ファイルなどのリソースを使い終わったあとに自動で解放するためのものです。
さらに、C#にはusing static、global using、C# 8.0以降で使えるusing宣言、.NET 6以降のテンプレートで見かける暗黙的global usingもあります。この記事では、C#のusingを初心者向けに整理し、それぞれの違いと使い方をコード例つきで解説します。
1. C#のusingとは?まず押さえるべき4つの意味
C#のusingには、大きく分けて次の意味があります。
| 種類 | 主な目的 | 例 |
|---|---|---|
| usingディレクティブ | 名前空間を省略して書く | using System; |
| usingステートメント | リソースを自動解放する | using (...) { } |
| using宣言 | スコープ終了時にリソースを自動解放する | using var file = ...; |
| using static | staticメンバーを型名なしで呼ぶ | using static System.Console; |
| global using | プロジェクト全体にusingを適用する | global using System; |
| 暗黙的global using | SDKが自動生成するglobal using | .csprojのImplicitUsings |
厳密には4つ以上ありますが、最初に理解すべき中心は「名前空間の省略」と「リソース解放」です。そこから派生して、staticやglobalの使い方を押さえると理解しやすくなります。
1-1. usingは「名前空間の省略」と「リソース解放」で使われるキーワード
C#のusingでまず覚えるべき役割は、次の2つです。
1つ目は、名前空間を省略してコードを書きやすくする役割です。
C#using System;
Console.WriteLine("Hello");
Consoleは本来System.Consoleという名前で参照できます。using System;を書くことで、System.Console.WriteLineではなくConsole.WriteLineと短く書けます。Microsoft Learnでも、usingディレクティブは完全修飾名を指定せずに名前空間内の型を使用できる仕組みとして説明されています。
2つ目は、ファイルやDB接続など、使い終わったあとに片付けが必要なリソースを自動で解放する役割です。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
この場合、usingブロックを抜けるとreader.Dispose()が自動的に呼ばれます。例外が発生した場合でもDisposeされるため、リソース解放漏れを防げます。
1-2. 初心者が混同しやすいusingディレクティブ・usingステートメント・using宣言の違い
初心者が混同しやすいのは、次の3つです。
C#// usingディレクティブ
using System;
C#// usingステートメント
using (var file = File.OpenRead("sample.txt"))
{
// fileを使う
}
C#// using宣言
using var file = File.OpenRead("sample.txt");
// fileを使う
usingディレクティブは、名前空間を省略するためにファイルの先頭などに書きます。
usingステートメントは、IDisposableを実装したオブジェクトを使い終わったら自動で解放するために使います。
using宣言は、C# 8.0以降で使える書き方で、ブロックを書かずにスコープ終了時に自動でDisposeできます。
同じusingでも、「コードを短くするためのusing」と「リソースを片付けるためのusing」がある、と分けて考えると理解しやすくなります。
1-3. static using・global usingまで含めた全体像
using staticは、特定の型のstaticメンバーを型名なしで呼び出せるようにする機能です。
C#using static System.Console;
WriteLine("Hello");
通常はConsole.WriteLineと書くところを、WriteLineだけで書けます。
global usingは、C# 10以降で使える機能です。
C#global using System;
global using System.Collections.Generic;
通常のusingは書いたファイルだけに効きますが、global usingはプロジェクト内のすべてのソースファイルに適用されます。Microsoft Learnでは、global修飾子はプロジェクト内のすべてのソースファイルに同じusingディレクティブを追加するのと同じ効果があると説明されています。
また、.NET 6以降のプロジェクトでは、ImplicitUsingsという設定によって、よく使う名前空間が自動的にglobal usingとして扱われる場合があります。これが「using System;を書いていないのにConsole.WriteLineが使える」理由のひとつです。
1-4. この記事で解決できること
この記事を読むと、次の疑問を解決できます。
| 疑問 | 解決できる内容 |
|---|---|
using System;とは何か | 名前空間を省略する仕組み |
usingブロックは何のためにあるか | IDisposableとDisposeの基本 |
using varとは何か | C# 8.0以降のusing宣言 |
using staticはいつ使うか | staticメンバーの省略記法 |
global usingとは何か | プロジェクト全体にusingを適用する方法 |
using System;が見えない理由 | 暗黙的global usingの仕組み |
| using関連のエラー対処 | 名前空間・参照・Disposeの確認方法 |
2. usingディレクティブとは?名前空間を省略して書くための仕組み
usingディレクティブは、名前空間に含まれる型を短い名前で使えるようにするための機能です。
たとえば、次のコードを見てください。
C#using System;
Console.WriteLine("Hello");
このusing System;があることで、System.Console.WriteLineではなくConsole.WriteLineと書けます。
2-1. using System; の意味
using System;は、「System名前空間にある型を、このファイル内で短く書けるようにする」という意味です。
System名前空間には、C#の基本的な処理でよく使う型が含まれています。
たとえば、次のような型です。
| 型 | 用途 |
|---|---|
Console | コンソールへの入出力 |
String | 文字列 |
DateTime | 日付と時刻 |
Exception | 例外 |
Math | 数学的な処理 |
using System;を書いておくと、次のように短く書けます。
C#using System;
Console.WriteLine(DateTime.Now);
using System;がない場合は、次のように完全修飾名で書く必要があります。
C#System.Console.WriteLine(System.DateTime.Now);
2-2. 名前空間とは何か
名前空間とは、クラスや構造体などの型を整理するための入れ物のようなものです。
C#では、多くの型が名前空間に分類されています。
C#namespace MyApp.Services
{
public class UserService
{
}
}
この例では、UserServiceクラスはMyApp.Services名前空間の中にあります。
名前空間を使う理由は、型の名前の衝突を防ぐためです。たとえば、別々のライブラリに同じUserServiceというクラスがあっても、名前空間が違えば区別できます。
C#MyApp.Services.UserService
OtherApp.Services.UserService
C#の名前空間は、コードを整理し、クラス名の衝突を避け、どの機能がどこに属しているかを分かりやすくするために使われます。Microsoft Learnでも、名前空間やusingディレクティブはC#コードの構造化に関わる仕組みとして説明されています。
2-3. usingを書かない場合の完全修飾名の書き方
usingを書かない場合、型は完全修飾名で指定します。
C#System.Console.WriteLine("Hello");
ConsoleはSystem名前空間にあるため、完全に書くとSystem.Consoleです。
List<T>を使う場合も同じです。
C#System.Collections.Generic.List<string> names =
new System.Collections.Generic.List<string>();
これでは長くて読みにくいため、通常は次のようにusingを書きます。
C#using System.Collections.Generic;
List<string> names = new List<string>();
usingは、コードの意味を変えるというより、「長い名前を省略して読みやすくする」ためのものです。
2-4. usingディレクティブの基本構文
usingディレクティブの基本構文は次のとおりです。
C#using 名前空間;
例です。
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
C#ファイルの先頭に書くことが多いです。
C#using System;
using System.Collections.Generic;
namespace SampleApp
{
public class Program
{
public static void Main()
{
List<string> names = new List<string>();
Console.WriteLine("Hello");
}
}
}
C# 10以降ではファイルスコープ名前空間を使って、次のように書くこともあります。
C#using System;
using System.Collections.Generic;
namespace SampleApp;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello");
}
}
2-5. よく使うusingディレクティブの例
よく使うusingには、次のようなものがあります。
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Threading.Tasks;
それぞれの用途は次のとおりです。
| using | 主な用途 |
|---|---|
using System; | Console、DateTime、Exceptionなど |
using System.Collections.Generic; | List<T>、Dictionary<TKey, TValue>など |
using System.Linq; | Where、Select、OrderByなどのLINQ |
using System.IO; | File、StreamReader、StreamWriterなど |
using System.Text; | StringBuilder、文字エンコーディングなど |
using System.Threading.Tasks; | Task、非同期処理など |
たとえば、List<string>を使うには次のように書きます。
C#using System.Collections.Generic;
List<string> names = new List<string>
{
"Alice",
"Bob",
"Charlie"
};
File.ReadAllTextを使う場合は、次のようにSystem.IOを使います。
C#using System.IO;
string text = File.ReadAllText("sample.txt");
2-6. usingディレクティブでできること・できないこと
usingディレクティブでできることは、名前空間内の型を短く書くことです。
C#using System;
Console.WriteLine("Hello");
ただし、usingを書いたからといって、ライブラリそのものが自動で追加されるわけではありません。
たとえば、外部ライブラリの型を使いたい場合、usingを書くだけでは不十分です。必要なNuGetパッケージやプロジェクト参照を追加したうえで、対応する名前空間をusingする必要があります。
また、usingはクラスやメソッドを「読み込む」命令ではありません。C言語やC++の#includeのようにファイルを展開するものでもありません。C#のusingディレクティブは、型名を解決しやすくするためのコンパイル時の仕組みです。
3. usingステートメントとは?IDisposableを自動でDisposeする書き方
usingステートメントは、使い終わったあとに片付けが必要なオブジェクトを自動的にDisposeするための構文です。
代表的な例は、ファイル操作です。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
このコードでは、usingブロックを抜けた時点でreader.Dispose()が自動的に呼ばれます。
3-1. usingステートメントの役割
usingステートメントの役割は、IDisposableを実装したオブジェクトを確実に破棄することです。
IDisposableとは、使い終わったあとにDisposeメソッドでリソースを解放できる型に実装されるインターフェイスです。
C#public interface IDisposable
{
void Dispose();
}
実際には、次のようなクラスでよく使われます。
| 種類 | 例 |
|---|---|
| ファイル操作 | StreamReader、FileStream |
| DB接続 | SqlConnection |
| ネットワーク接続 | HttpClientなど |
| 画像・描画関連 | Bitmapなど |
| メモリ以外のリソース | OSハンドル、接続、ストリームなど |
usingステートメントは、ブロックを抜けたときにDisposeが呼ばれるようにする安全な書き方です。Microsoft Learnでは、usingステートメントはブロックを抜けると取得したIDisposableインスタンスを破棄し、ブロック内で例外が発生しても破棄されると説明されています。
3-2. ファイル・DB接続・ネットワーク接続でusingが必要な理由
ファイル、DB接続、ネットワーク接続などは、メモリだけでなくOSや外部サービスのリソースを使います。
たとえば、ファイルを開いたまま閉じないと、次のような問題が起こることがあります。
| 対象 | 解放しない場合の問題 |
|---|---|
| ファイル | 他の処理がファイルを開けない |
| DB接続 | 接続数が不足する |
| ネットワーク | ソケットや接続が残る |
| ストリーム | バッファが正しく書き込まれない |
| OSリソース | ハンドルリークが発生する |
C#にはガベージコレクションがありますが、ガベージコレクションは主にマネージドメモリを回収する仕組みです。ファイルハンドルやDB接続のような外部リソースは、使い終わったタイミングで明示的に解放する必要があります。
そのため、IDisposableを実装しているオブジェクトは、基本的にusingで囲むのが安全です。
3-3. usingステートメントの基本構文
usingステートメントの基本構文は次のとおりです。
C#using (リソースを作成する式)
{
// リソースを使う処理
}
例です。
C#using (var stream = new FileStream("sample.txt", FileMode.Open))
{
// streamを使う
}
複数のリソースを使うこともできます。
C#using (var input = new StreamReader("input.txt"))
using (var output = new StreamWriter("output.txt"))
{
string text = input.ReadToEnd();
output.Write(text);
}
この場合、ブロックを抜けるとoutput、inputの順にDisposeされます。
3-4. try-finallyとusingステートメントの関係
usingステートメントは、内部的にはtry-finallyに近い考え方です。
次のコードを見てください。
C#using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
これは概念的には次のような処理に近いです。
C#var reader = new StreamReader("sample.txt");
try
{
Console.WriteLine(reader.ReadToEnd());
}
finally
{
if (reader != null)
{
reader.Dispose();
}
}
tryブロック内で例外が発生しても、finallyは実行されます。そのため、Disposeが呼ばれます。
つまり、usingステートメントは「Disposeを忘れないための簡潔なtry-finally」と考えると分かりやすいです。
3-5. usingステートメントの実例
ファイルを読み込む例です。
C#using System;
using System.IO;
class Program
{
static void Main()
{
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
}
}
ファイルへ書き込む例です。
C#using System.IO;
using (var writer = new StreamWriter("log.txt"))
{
writer.WriteLine("処理を開始しました");
writer.WriteLine("処理を終了しました");
}
DB接続の例です。
C#using System.Data.SqlClient;
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT COUNT(*) FROM Users";
int count = (int)command.ExecuteScalar();
Console.WriteLine(count);
}
}
このように、usingステートメントは「開いたら閉じる」「確保したら解放する」必要がある処理でよく使われます。
3-6. usingステートメントを使わないと起こる問題
usingステートメントを使わず、Disposeも呼ばない場合、リソースが解放されない可能性があります。
悪い例です。
C#var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
// reader.Dispose(); を忘れている
このコードでは、readerを閉じる処理がありません。処理が短ければすぐ問題にならないこともありますが、繰り返し実行される処理ではリソースリークの原因になります。
改善例です。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
IDisposableを実装している型を使うときは、「Disposeが必要か」を確認し、必要ならusingを使う習慣をつけましょう。
4. using宣言とは?C# 8.0以降で使えるシンプルなリソース解放
using宣言は、C# 8.0以降で使える、よりシンプルなリソース解放の書き方です。
従来のusingステートメントはブロックを書きます。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
using宣言では、次のように書けます。
C#using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
この場合、readerは現在のスコープを抜けるタイミングでDisposeされます。
4-1. using宣言の基本構文
using宣言の基本構文は次のとおりです。
C#using var 変数名 = new IDisposableを実装した型();
例です。
C#using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
型を明示して書くこともできます。
C#using StreamReader reader = new StreamReader("sample.txt");
using宣言は、usingブロックを作らずに、変数のスコープ終了時にDisposeする構文です。Microsoft Learnでも、using宣言で宣言されたローカル変数はスコープの終わりで破棄されると説明されています。
4-2. usingステートメントとの違い
usingステートメントとusing宣言の主な違いは、Disposeされるタイミングを決めるスコープです。
usingステートメントの場合です。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
} // ここでDispose
using宣言の場合です。
C#using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
// メソッドやブロックの終わりでDispose
比較すると次のようになります。
| 項目 | usingステートメント | using宣言 |
|---|---|---|
| 書き方 | using (...) { } | using var x = ...; |
| Disposeのタイミング | usingブロック終了時 | 現在のスコープ終了時 |
| ブロック | 必要 | 不要 |
| ネスト | 深くなりやすい | 浅く書ける |
| 対応バージョン | 以前から利用可能 | C# 8.0以降 |
4-3. スコープ終了時にDisposeされる仕組み
using宣言では、宣言した変数が属するスコープを抜けるとDisposeされます。
たとえば、メソッド内で宣言した場合です。
C#void ReadFile()
{
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
} // ここでreader.Dispose()
ifブロック内で宣言した場合です。
C#if (File.Exists("sample.txt"))
{
using var reader = new StreamReader("sample.txt");
Console.WriteLine(reader.ReadToEnd());
} // ここでreader.Dispose()
スコープが広いほど、Disposeされるタイミングも遅くなります。そのため、必要以上にリソースを保持しないように注意が必要です。
4-4. using宣言を使うメリット
using宣言のメリットは、コードを浅く、読みやすく書けることです。
従来の書き方です。
C#using (var reader = new StreamReader("input.txt"))
using (var writer = new StreamWriter("output.txt"))
{
string text = reader.ReadToEnd();
writer.Write(text);
}
using宣言を使うと、次のように書けます。
C#using var reader = new StreamReader("input.txt");
using var writer = new StreamWriter("output.txt");
string text = reader.ReadToEnd();
writer.Write(text);
ネストが減るため、処理の本筋が見やすくなります。
特に、メソッド全体でリソースを使う場合や、短い処理ではusing宣言が読みやすいことが多いです。
4-5. using宣言を使うときの注意点
using宣言では、Disposeされるタイミングがスコープ終了時になるため、思ったより長くリソースを保持してしまうことがあります。
たとえば、次のコードです。
C#void Process()
{
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
// ここから先ではreaderを使わない
DoOtherHeavyWork();
} // readerはここでDispose
readerを使い終わったあとも、メソッド終了までファイルが開かれたままになります。
このような場合は、usingステートメントでスコープを明確にしたほうがよいです。
C#void Process()
{
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
} // ここでDispose
DoOtherHeavyWork();
}
using宣言は便利ですが、「いつDisposeされるか」を意識して使うことが大切です。
5. using staticとは?staticメンバーをクラス名なしで呼び出す方法
using staticは、特定の型のstaticメンバーを、型名なしで使えるようにする機能です。
通常、Console.WriteLineは次のように書きます。
C#Console.WriteLine("Hello");
using static System.Console;を書くと、次のように書けます。
C#using static System.Console;
WriteLine("Hello");
5-1. using staticの基本構文
using staticの基本構文は次のとおりです。
C#using static 型名;
例です。
C#using static System.Console;
using static System.Math;
using staticは名前空間ではなく、型に対して指定します。
正しい例です。
C#using static System.Console;
間違った例です。
C#using static System; // Systemは名前空間なので不可
using staticは、指定した型のstaticメンバーや入れ子になった型をインポートする機能です。Microsoft Learnでも、static修飾子は名前空間内の型をすべてインポートするのではなく、1つの型からstaticメンバーと入れ子にされた型をインポートすると説明されています。
5-2. Console.WriteLineをWriteLineだけで書く例
using static System.Console;を使うと、Console.WriteLineをWriteLineだけで書けます。
C#using static System.Console;
WriteLine("名前を入力してください:");
string? name = ReadLine();
WriteLine($"こんにちは、{name}さん");
通常の書き方です。
C#Console.WriteLine("名前を入力してください:");
string? name = Console.ReadLine();
Console.WriteLine($"こんにちは、{name}さん");
短いサンプルコードやコンソールアプリでは、using static System.Console;を使うと見た目がすっきりします。
5-3. Math.PIやMath.Sqrtを短く書く例
Mathクラスのstaticメンバーも短く書けます。
通常の書き方です。
C#double radius = 5;
double area = Math.PI * Math.Pow(radius, 2);
double root = Math.Sqrt(25);
using static System.Math;を使うと、次のように書けます。
C#using static System.Math;
double radius = 5;
double area = PI * Pow(radius, 2);
double root = Sqrt(25);
数式が多いコードでは、Math.がなくなることで式が読みやすくなる場合があります。
5-4. using staticを使うメリット
using staticのメリットは、staticメンバーを短く書けることです。
特に、次のような場面で便利です。
| 場面 | 例 |
|---|---|
| コンソールアプリ | WriteLine、ReadLine |
| 数学計算 | PI、Sqrt、Pow |
| テストコード | Assert系メソッド |
| 定数を多く使うコード | SomeConstants.Valueの省略 |
たとえば、単体テストでは次のような書き方を見かけることがあります。
C#using static Xunit.Assert;
Equal(10, result);
NotNull(user);
ただし、便利だからといって何でもusing staticにすると、どのクラスのメソッドなのか分かりにくくなります。
5-5. 可読性が下がるケースと注意点
using staticを使いすぎると、コードの出どころが分かりにくくなります。
たとえば、次のコードです。
C#WriteLine("Hello");
Sqrt(25);
Equal(5, result);
短くは書けていますが、初心者が見るとWriteLine、Sqrt、Equalがどこから来たのか分かりにくいかもしれません。
また、複数の型に同じ名前のstaticメソッドがあると、名前の衝突が起こる場合があります。
C#using static A.Utility;
using static B.Utility;
// DoSomething(); がどちらのメソッドか曖昧になる可能性
using staticは、短く書くことよりも、読みやすさを優先して使いましょう。
6. global usingとは?プロジェクト全体にusingを適用する機能
global usingは、C# 10以降で使える機能で、指定したusingをプロジェクト全体に適用できます。
通常のusingは、そのファイルだけに有効です。
C#using System;
global usingは、プロジェクト内のすべてのC#ファイルに有効です。
C#global using System;
6-1. global usingの基本構文
global usingの基本構文は次のとおりです。
C#global using 名前空間;
例です。
C#global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
using staticと組み合わせることもできます。
C#global using static System.Console;
エイリアスと組み合わせることもできます。
C#global using ProjectList = System.Collections.Generic.List<string>;
ただし、プロジェクト全体に影響するため、使う場所や内容は慎重に選ぶ必要があります。
6-2. 通常のusingディレクティブとの違い
通常のusingとglobal usingの違いは、適用範囲です。
| 種類 | 適用範囲 |
|---|---|
using System; | 書いたファイルだけ |
global using System; | プロジェクト内の全ファイル |
通常のusingです。
C#// Program.cs
using System;
Console.WriteLine("Hello");
このusing System;は、基本的にProgram.cs内でのみ有効です。
global usingです。
C#// GlobalUsings.cs
global using System;
このように書くと、別ファイルでもSystem名前空間の型を短く書けます。
C#// UserService.cs
Console.WriteLine("UserService");
global usingは、プロジェクト内の各ソースファイルに同じusingを追加するのと同じ効果があります。
6-3. C# 10以降で導入された背景
global usingは、毎回同じusingをファイル先頭に書く手間を減らすために導入されました。
多くのC#プロジェクトでは、次のようなusingが複数ファイルで繰り返し使われます。
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
ファイルが増えるほど、同じusingが何度も現れます。
global usingを使えば、共通して使う名前空間を1か所にまとめられます。
C#// GlobalUsings.cs
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
C# 10では、global usingや暗黙的usingによって、各ファイルの先頭に書くusingの量を減らせるようになりました。Microsoftの.NET Blogでも、C# 10のglobal usingとimplicit usingsは、各ファイルの先頭に指定するusingの数を減らすための機能として紹介されています。
6-4. global usingを置く場所
global usingは、プロジェクト内の任意の.csファイルに書けます。
ただし、実務では分かりやすさのために、専用ファイルを作ることが多いです。
例です。
MyApp
├─ Program.cs
├─ Services
│ └─ UserService.cs
└─ GlobalUsings.cs
GlobalUsings.csの中身です。
C#global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
このようにまとめておくと、プロジェクト全体で使っている共通の名前空間が分かりやすくなります。
注意点として、global usingは通常のusingよりも前に評価されるイメージで、プロジェクト全体に影響します。特定のファイルだけで使う名前空間までglobalにすると、依存関係が見えにくくなります。
6-5. 複数ファイルで同じusingを書く手間を減らす方法
複数ファイルで同じusingを書いている場合は、global usingにまとめるとすっきりします。
たとえば、複数のファイルで次のusingが繰り返されているとします。
C#using System;
using System.Collections.Generic;
using System.Linq;
各ファイルから削除して、GlobalUsings.csにまとめます。
C#global using System;
global using System.Collections.Generic;
global using System.Linq;
これで各ファイルでは、必要なクラスやメソッドをそのまま短い名前で使えます。
C#public class UserService
{
public List<string> GetNames()
{
return new List<string> { "Alice", "Bob" }
.Where(name => name.StartsWith("A"))
.ToList();
}
}
共通で使う名前空間はglobal usingに、特定のファイルだけで使う名前空間は通常のusingにするのがおすすめです。
6-6. global usingを使いすぎるデメリット
global usingを使いすぎると、次のようなデメリットがあります。
| デメリット | 内容 |
|---|---|
| 依存関係が見えにくい | ファイル単体で必要な名前空間が分かりにくい |
| 名前の衝突が起きやすい | 同じ型名が複数の名前空間にある場合に混乱する |
| 不要なusingが増える | ほとんど使わない名前空間まで全体に適用される |
| 初心者が混乱しやすい | どこでusingされているのか分かりにくい |
たとえば、System.IOを一部のファイルでしか使わないなら、無理にglobalにする必要はありません。
C#// ファイル操作をするクラスだけでよい
using System.IO;
global usingは便利ですが、「プロジェクト全体で本当によく使うもの」に限定すると管理しやすくなります。
7. 暗黙的global usingとは?.NET 6以降でusing Systemが見えない理由
.NET 6以降のプロジェクトを作ると、Program.csにusing System;がないのに、次のコードが動くことがあります。
C#Console.WriteLine("Hello, World!");
これは、暗黙的global usingが有効になっているためです。
7-1. 暗黙的global usingの概要
暗黙的global usingとは、.NET SDKがプロジェクトの種類に応じて、よく使う名前空間を自動的にglobal usingとして追加する仕組みです。
たとえば、コンソールアプリではSystemなどの基本的な名前空間が自動で使えるようになります。
そのため、次のようにusing System;を書かなくても、Consoleを使える場合があります。
C#Console.WriteLine("Hello");
暗黙的global usingはC#の文法そのものというより、.NET SDK側の機能です。C# 10のglobal usingと組み合わさることで、テンプレートから生成されたプロジェクトのコードが短くなっています。
7-2. Program.csにusing System;がなくてもConsoleが使える理由
ConsoleはSystem名前空間にある型です。
通常であれば、次のように書きます。
C#using System;
Console.WriteLine("Hello");
または完全修飾名で書きます。
C#System.Console.WriteLine("Hello");
しかし、暗黙的global usingが有効なプロジェクトでは、SDKが内部的に次のようなusingを用意してくれます。
C#global using System;
そのため、ソースコード上にusing System;が見えなくても、Console.WriteLineと書けます。
初心者にとっては、「参考書ではusing System;があるのに、自分のプロジェクトにはない」と混乱しやすいポイントです。これはC#や.NETのバージョン、プロジェクトテンプレートの違いによって起こります。
7-3. ImplicitUsingsの設定場所
暗黙的global usingは、.csprojファイルのImplicitUsingsで設定されます。
例です。
XML<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
この中の次の部分が、暗黙的global usingの設定です。
XML<ImplicitUsings>enable</ImplicitUsings>
enableになっていると、プロジェクトの種類に応じた名前空間が自動的にglobal usingされます。
7-4. 暗黙的global usingを有効・無効にする方法
暗黙的global usingを有効にするには、.csprojに次のように書きます。
XML<ImplicitUsings>enable</ImplicitUsings>
無効にするには、次のように書きます。
XML<ImplicitUsings>disable</ImplicitUsings>
無効にした場合、必要なusingは自分で明示的に書く必要があります。
C#using System;
Console.WriteLine("Hello");
学習目的では、あえてImplicitUsingsを無効にして、どの名前空間が必要かを確認するのもよい方法です。
7-5. 初心者が混乱しやすいポイント
暗黙的global usingで初心者が混乱しやすいのは、次の点です。
| 混乱ポイント | 理由 |
|---|---|
using System;がないのに動く | SDKが自動でglobal usingしている |
| 教材と自分のコードが違う | C#や.NETのバージョンが違う |
| エラーが出る環境と出ない環境がある | ImplicitUsings設定が違う |
| どのusingが必要か分かりにくい | 見えないusingが存在する |
特に、古い教材ではusing System;が必ず書かれていることが多いです。一方、新しい.NETテンプレートでは、Program.csが非常に短くなっています。
C#Console.WriteLine("Hello, World!");
この違いは、トップレベルステートメントや暗黙的global usingによって、最小限のコードでプログラムを書けるようになったためです。
8. C#のusingの違いを一覧表で比較
ここまで解説したusingの違いを、一覧表で整理します。
8-1. usingディレクティブ・usingステートメント・using宣言の違い
| 種類 | 目的 | 書く場所 | 例 |
|---|---|---|---|
| usingディレクティブ | 名前空間を省略する | ファイル先頭など | using System; |
| usingステートメント | リソースを自動解放する | 処理の中 | using (...) { } |
| using宣言 | スコープ終了時にリソースを自動解放する | 処理の中 | using var file = ...; |
コード例です。
C#// usingディレクティブ
using System;
using System.IO;
// usingステートメント
using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
// using宣言
using var writer = new StreamWriter("log.txt");
writer.WriteLine("ログ");
最初に覚えるなら、using System;のような名前空間用のusingと、using (...) { }のようなリソース解放用のusingを区別することが重要です。
8-2. using static・global using・暗黙的global usingの違い
| 種類 | 目的 | 例 |
|---|---|---|
using static | staticメンバーを型名なしで呼ぶ | using static System.Console; |
global using | プロジェクト全体にusingを適用する | global using System; |
| 暗黙的global using | SDKが自動でglobal usingを生成する | <ImplicitUsings>enable</ImplicitUsings> |
using staticは「何を短く呼ぶか」に関する機能です。
C#using static System.Console;
WriteLine("Hello");
global usingは「どこまで有効にするか」に関する機能です。
C#global using System;
暗黙的global usingは「SDKが自動で用意するglobal using」です。
XML<ImplicitUsings>enable</ImplicitUsings>
それぞれ目的が違うため、同じusingという名前でも役割を分けて考えましょう。
8-3. 目的別に見るusingの使い分け
目的別に見ると、使い分けは次のようになります。
| やりたいこと | 使うusing |
|---|---|
System.ConsoleをConsoleと書きたい | usingディレクティブ |
| ファイルを使い終わったら閉じたい | usingステートメント |
| ブロックを増やさずにDisposeしたい | using宣言 |
Console.WriteLineをWriteLineと書きたい | using static |
| すべてのファイルで共通のusingを使いたい | global using |
using System;を書かずに基本名前空間を使いたい | 暗黙的global using |
初心者におすすめの判断基準は、次のとおりです。
型名が長い → usingディレクティブ
Disposeが必要 → usingステートメントまたはusing宣言
staticメンバーを短くしたい → using static
全ファイルで共通にしたい → global using
usingが見えないのに動く → 暗黙的global using
8-4. C#のバージョン別に使えるusing機能
主なusing関連機能をバージョン別に整理すると、次のようになります。
| 機能 | 対応バージョンの目安 |
|---|---|
| usingディレクティブ | 初期のC#から |
| usingステートメント | 初期のC#から |
| using static | C# 6.0以降 |
| using宣言 | C# 8.0以降 |
| global using | C# 10以降 |
| 暗黙的global using | .NET 6以降のSDKテンプレートでよく使われる |
global usingはC# 10の機能として導入され、暗黙的global usingと合わせて、ファイル先頭のusingを減らす方向に進みました。
古いプロジェクトや古い教材では、using System;やnamespace、class Program、static void Mainが明示的に書かれていることがあります。一方、新しい.NETのテンプレートでは、それらが省略されて見える場合があります。
9. usingでよくあるエラーと解決方法
C#のusingでよくあるエラーは、名前空間、参照設定、Dispose、名前の衝突に関するものです。
9-1. 型または名前空間の名前が見つかりません
よくあるエラーです。
型または名前空間の名前 'List' が見つかりません
原因は、必要な名前空間をusingしていないことです。
悪い例です。
C#List<string> names = new List<string>();
List<T>はSystem.Collections.Generic名前空間にあるため、次のusingを追加します。
C#using System.Collections.Generic;
List<string> names = new List<string>();
または完全修飾名で書きます。
C#System.Collections.Generic.List<string> names =
new System.Collections.Generic.List<string>();
Visual StudioやVisual Studio Codeでは、型名にカーソルを合わせると、必要なusingを自動追加できる場合があります。
9-2. usingを追加してもエラーが消えない場合
usingを追加してもエラーが消えない場合は、名前空間だけでなく、参照やパッケージが不足している可能性があります。
たとえば、外部ライブラリの型を使う場合です。
C#using Newtonsoft.Json;
var json = JsonConvert.SerializeObject(obj);
この場合、using Newtonsoft.Json;を書くだけでは不十分です。プロジェクトにNewtonsoft.Jsonパッケージが追加されている必要があります。
NuGetで追加する例です。
Bashdotnet add package Newtonsoft.Json
その後、必要なusingを書きます。
C#using Newtonsoft.Json;
usingは参照済みの型を短く書くためのもので、ライブラリそのものをインストールする機能ではありません。
9-3. NuGetパッケージや参照設定が不足している場合
外部ライブラリを使う場合、必要な作業は主に2つです。
1つ目は、NuGetパッケージやプロジェクト参照を追加することです。
Bashdotnet add package パッケージ名
2つ目は、コード内で必要な名前空間をusingすることです。
C#using パッケージの名前空間;
たとえば、Entity Framework Coreを使う場合は、パッケージの追加とusingの両方が必要になります。
Bashdotnet add package Microsoft.EntityFrameworkCore
C#using Microsoft.EntityFrameworkCore;
エラーが出たときは、次の順番で確認すると解決しやすいです。
| 確認項目 | 内容 |
|---|---|
| 型名は正しいか | スペルミスがないか |
| usingは正しいか | 対応する名前空間を指定しているか |
| パッケージは入っているか | NuGet参照があるか |
| プロジェクト参照はあるか | 別プロジェクトの型を参照できるか |
| 対象フレームワークは合っているか | そのAPIが使える.NETバージョンか |
9-4. using System;が不要に見える理由
最近のC#プロジェクトでは、次のようなコードだけで動くことがあります。
C#Console.WriteLine("Hello");
using System;がないのにConsoleが使える理由は、暗黙的global usingが有効になっているためです。
.csprojに次の設定がある場合、SDKがよく使う名前空間を自動的にglobal usingとして扱います。
XML<ImplicitUsings>enable</ImplicitUsings>
そのため、見た目上はusing System;がなくても、実際にはプロジェクト全体でSystemが使える状態になっています。
古い教材と新しいテンプレートを見比べると違って見えますが、どちらも間違いではありません。
9-5. Disposeされない・リソースが解放されない場合
リソースが解放されない場合は、usingステートメントまたはusing宣言を使っているか確認しましょう。
悪い例です。
C#var stream = new FileStream("sample.txt", FileMode.Open);
// streamを使う
// Disposeを忘れている
改善例です。
C#using (var stream = new FileStream("sample.txt", FileMode.Open))
{
// streamを使う
}
または、using宣言を使います。
C#using var stream = new FileStream("sample.txt", FileMode.Open);
// streamを使う
注意点として、using宣言の場合はスコープ終了までDisposeされません。すぐに解放したい場合は、usingステートメントでブロックを明確にするほうが安全です。
9-6. using staticでメソッド名が衝突する場合
using staticを複数使うと、同じ名前のメソッドやプロパティが衝突することがあります。
例です。
C#using static MyApp.Utilities.TextHelper;
using static MyApp.Utilities.LogHelper;
Write("message");
両方のクラスにWriteメソッドがある場合、どちらを呼ぶべきか曖昧になる可能性があります。
このような場合は、型名を明示しましょう。
C#TextHelper.Write("message");
LogHelper.Write("message");
using staticは便利ですが、名前が一般的なメソッドには使いすぎないほうが安全です。
10. 初心者向け:usingの使い分け判断フロー
C#のusingで迷ったときは、「何をしたいのか」から判断すると分かりやすいです。
10-1. 名前空間を省略したいならusingディレクティブ
型名を短く書きたい場合は、usingディレクティブを使います。
C#using System.Collections.Generic;
List<string> names = new List<string>();
完全修飾名で書くと長くなる場合に便利です。
C#System.Collections.Generic.List<string> names =
new System.Collections.Generic.List<string>();
基本的には、必要な名前空間をファイル先頭にusingとして追加します。
10-2. リソースを確実に解放したいならusingステートメントまたはusing宣言
ファイル、ストリーム、DB接続など、Disposeが必要なものを使う場合は、usingステートメントまたはusing宣言を使います。
スコープを明確にしたいなら、usingステートメントがおすすめです。
C#using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
コードを浅く書きたいなら、using宣言が便利です。
C#using var reader = new StreamReader("sample.txt");
Console.WriteLine(reader.ReadToEnd());
どちらを使っても、目的は「Disposeを忘れないこと」です。
10-3. staticメンバーを短く書きたいならusing static
Console.WriteLineやMath.Sqrtのようなstaticメンバーを短く書きたい場合は、using staticを使います。
C#using static System.Console;
using static System.Math;
WriteLine(Sqrt(25));
ただし、短くなりすぎて意味が分かりにくくなる場合は、通常どおり型名を書いたほうがよいです。
C#Console.WriteLine(Math.Sqrt(25));
初心者のうちは、using staticは必要な場面だけに限定するのがおすすめです。
10-4. プロジェクト全体で共通化したいならglobal using
すべてのファイルでよく使う名前空間がある場合は、global usingを検討します。
C#global using System;
global using System.Collections.Generic;
global using System.Linq;
専用のGlobalUsings.csを作ると管理しやすくなります。
GlobalUsings.cs
C#global using System;
global using System.Collections.Generic;
global using System.Linq;
ただし、特定のファイルでしか使わない名前空間までglobalにすると、依存関係が分かりにくくなります。
10-5. 迷ったときのおすすめの書き方
初心者が迷ったときは、次の方針がおすすめです。
| 状況 | おすすめ |
|---|---|
| 名前空間を省略したい | 通常のusingを使う |
| Disposeが必要 | usingステートメントを使う |
| 慣れてきた | using宣言も使う |
| staticメンバーを短くしたい | 必要な場合だけusing staticを使う |
| 共通usingが多い | global usingを検討する |
| 学習中 | 暗黙的global usingに頼りすぎず、必要なusingを理解する |
学習段階では、まず次の2つを確実に理解しましょう。
C#using System;
C#using (var resource = ...)
{
}
この2つを理解できれば、C#のusingの基礎はかなり整理できます。
11. C#のusingに関するよくある質問
最後に、C#のusingについて初心者が疑問に感じやすいポイントをQ&A形式で整理します。
11-1. using System;は必ず必要ですか?
必ず必要とは限りません。
Console.WriteLineのように短く書きたい場合は、通常はusing System;が必要です。
C#using System;
Console.WriteLine("Hello");
ただし、完全修飾名で書けばusing System;は不要です。
C#System.Console.WriteLine("Hello");
また、暗黙的global usingが有効なプロジェクトでは、using System;を書かなくてもConsoleが使える場合があります。
XML<ImplicitUsings>enable</ImplicitUsings>
つまり、using System;が必要かどうかは、プロジェクト設定やコードの書き方によって変わります。
11-2. usingとincludeの違いは何ですか?
C#のusingと、C言語やC++の#includeは別物です。
#includeは、指定したファイルの内容を取り込むプリプロセッサ命令です。
一方、C#のusingディレクティブは、名前空間内の型を短く書けるようにするためのものです。
C#using System;
これはSystem名前空間を「ファイルとして読み込んでいる」のではありません。System.ConsoleをConsoleと書けるようにしているだけです。
外部ライブラリを使う場合は、usingだけでなく、NuGetパッケージや参照設定も必要です。
11-3. usingディレクティブはパフォーマンスに影響しますか?
基本的に、usingディレクティブは実行時のパフォーマンスには影響しません。
using System;を書いたからといって、プログラム実行時にSystem名前空間のすべての型が読み込まれるわけではありません。
usingディレクティブは、コンパイル時に型名を解決するための仕組みです。
C#using System;
Console.WriteLine("Hello");
これは、次のように完全修飾名で書く手間を省いているだけです。
C#System.Console.WriteLine("Hello");
ただし、使っていないusingが大量にあると、コードの見通しが悪くなります。パフォーマンスよりも可読性のために整理するのがおすすめです。
11-4. 使っていないusingは削除してもいいですか?
使っていないusingは、基本的に削除して問題ありません。
たとえば、次のコードでSystem.IOを使っていないなら削除できます。
C#using System;
using System.IO;
Console.WriteLine("Hello");
整理後です。
C#using System;
Console.WriteLine("Hello");
Visual StudioなどのIDEには、未使用のusingを削除する機能があります。
ただし、条件付きコンパイルや今後使う予定のコードがある場合は、削除によってビルドエラーになることもあります。削除後はビルドして確認しましょう。
11-5. usingステートメントとusing宣言はどちらを使うべきですか?
どちらもDisposeを自動で呼ぶための構文です。
明確なブロックでリソースの使用範囲を示したい場合は、usingステートメントがおすすめです。
C#using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
コードを浅く書きたい場合や、メソッド全体で使う場合は、using宣言が便利です。
C#using var reader = new StreamReader("sample.txt");
Console.WriteLine(reader.ReadToEnd());
初心者のうちは、Disposeされる範囲が分かりやすいusingステートメントから使い始めるとよいです。慣れてきたら、using宣言も使い分けましょう。
11-6. global usingは初心者でも使っていいですか?
初心者でもglobal usingを使って問題ありません。
ただし、最初は「どのファイルで何のusingが効いているのか」が分かりにくくなることがあります。
学習中は、まず通常のusingを理解するのがおすすめです。
C#using System;
using System.Collections.Generic;
そのうえで、複数ファイルで同じusingが何度も出てくるようになったら、global usingを使うと便利です。
C#global using System;
global using System.Collections.Generic;
プロジェクト全体で頻繁に使う名前空間だけをglobalにし、特定のファイルだけで使う名前空間は通常のusingにするのが分かりやすい使い方です。
まとめ
C#のusingは、同じキーワードでも複数の意味があります。
まず押さえるべきなのは、次の2つです。
C#using System;
これは、名前空間を省略して型を短く書くためのusingディレクティブです。
C#using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
これは、リソースを自動でDisposeするためのusingステートメントです。
さらに、C# 8.0以降ではusing宣言を使って、ブロックを書かずにリソースを自動解放できます。
C#using var reader = new StreamReader("sample.txt");
staticメンバーを短く書きたい場合は、using staticを使います。
C#using static System.Console;
WriteLine("Hello");
プロジェクト全体で共通のusingを使いたい場合は、global usingを使います。
C#global using System;
.NET 6以降のプロジェクトでは、ImplicitUsingsによって暗黙的global usingが有効になり、using System;が見えなくてもConsole.WriteLineが使える場合があります。
C#のusingで迷ったら、次のように判断しましょう。
| 目的 | 使う機能 |
|---|---|
| 名前空間を省略したい | usingディレクティブ |
| リソースを確実に解放したい | usingステートメント |
| ブロックを減らしてDisposeしたい | using宣言 |
| staticメンバーを短く書きたい | using static |
| プロジェクト全体で共通化したい | global using |
| usingが見えない理由を知りたい | 暗黙的global using |
usingはC#の基本ですが、正しく理解するとコードの読みやすさと安全性が大きく向上します。最初はusing System;とusing (...) { }の違いから理解し、慣れてきたらusing宣言、using static、global usingへと学習を広げていきましょう。

