C# usingとは?namespaceとDisposeの使い方・違いを初心者向けに解説
はじめに
C#を学び始めると、かなり早い段階で using というキーワードに出会います。
たとえば、次のようなコードです。
C#using System;
Console.WriteLine("Hello, C#");
一方で、ファイル操作やデータベース接続のサンプルでは、次のような using も登場します。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
どちらも同じ using ですが、意味はまったく同じではありません。
C#の using には、大きく分けて「namespaceを省略して書くためのusing」と「Disposeを自動で呼び出すためのusing」があります。初心者が混乱しやすいポイントは、同じキーワードなのに使われる場所や目的が異なることです。
この記事では、C# usingの基本を初心者向けに整理しながら、namespace、Dispose、usingステートメント、using宣言、global usingなどの違いをわかりやすく解説します。
1. C#のusingとは?初心者が最初に知るべき2つの意味
C#の using は、主に次の2つの目的で使われます。
1つ目は、namespaceを省略してクラス名を短く書くための using です。
C#using System;
Console.WriteLine("Hello");
2つ目は、使い終わったオブジェクトの Dispose を自動で呼び出すための using です。
C#using (var file = new StreamReader("sample.txt"))
{
Console.WriteLine(file.ReadToEnd());
}
同じ using でも、前者はコードの先頭に書くことが多く、後者は処理の中でオブジェクトを囲むように書きます。
1-1. usingは「namespaceの省略」と「Disposeの自動実行」で使われる
C# usingを理解するときは、まず次の2種類を分けて考えることが重要です。
C#using System;
これは usingディレクティブ と呼ばれます。
System というnamespaceを読み込むことで、System.Console と書かずに Console と短く書けるようになります。
一方、次のような書き方は usingステートメント と呼ばれます。
C#using (var stream = new FileStream("sample.txt", FileMode.Open))
{
// ファイルを使う処理
}
これは、using ブロックを抜けたタイミングで stream.Dispose() を自動的に呼び出す仕組みです。
つまり、C#のusingには次のような違いがあります。
| 種類 | 主な目的 | 書く場所 |
|---|---|---|
| usingディレクティブ | namespaceを省略する | ファイルの先頭など |
| usingステートメント | Disposeを自動実行する | メソッド内など |
| using宣言 | Disposeを自動実行する簡潔な書き方 | メソッド内など |
1-2. 同じusingでも役割が違うため混乱しやすい理由
初心者がC# usingで混乱しやすい理由は、同じ単語が複数の文脈で使われるからです。
たとえば、次の2つはどちらも using ですが、意味が違います。
C#using System;
C#using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
前者は「System namespace内のクラスを短く書けるようにする」ためのものです。
後者は「reader を使い終わったら自動的に後片付けする」ためのものです。
英語の using には「使う」という意味がありますが、C#では文法上の役割がいくつかに分かれています。そのため、コードのどこに書かれているかを見ると意味を判断しやすくなります。
1-3. この記事で解決できること
この記事を読むと、次のような疑問を解決できます。
C#の using System; は何をしているのか。
using と namespace は何が違うのか。
Dispose とは何か。
using ブロックを使うと何が便利なのか。
usingステートメント と using宣言 はどう違うのか。
using static、usingエイリアス、global using はどんな場面で使うのか。
特に初心者のうちは、すべてを一度に暗記する必要はありません。まずは「namespaceを省略するusing」と「Disposeを自動実行するusing」の2つを区別できれば十分です。
2. namespaceとは?usingでクラス名を短く書ける仕組み
C#のusingを理解するには、まず namespace を知っておく必要があります。
namespaceは、クラスやインターフェイスなどを分類するための名前空間です。簡単に言えば、クラスを整理するためのフォルダのようなものです。
2-1. namespaceの基本的な役割
C#には多くのクラスがあります。
たとえば、画面に文字を表示する Console クラス、日付や時刻を扱う DateTime 構造体、ファイルを扱う File クラスなどがあります。
これらのクラスがすべて同じ場所にあると、名前の衝突や管理の問題が起きやすくなります。
そこで、C#ではnamespaceを使ってクラスを分類します。
C#namespace MyApp.Models
{
public class User
{
public string Name { get; set; }
}
}
この場合、User クラスは MyApp.Models というnamespaceに属しています。
別の場所からこのクラスを使う場合は、本来であれば次のように完全な名前で指定できます。
C#MyApp.Models.User user = new MyApp.Models.User();
このような書き方を完全修飾名と呼びます。
2-2. usingディレクティブとは
usingディレクティブ は、namespaceをあらかじめ指定しておくことで、クラス名を短く書けるようにする仕組みです。
たとえば、次のように書くとします。
C#using MyApp.Models;
User user = new User();
using MyApp.Models; を書いているため、MyApp.Models.User と毎回書かなくても、User だけで使えるようになります。
つまり、usingディレクティブは「このファイルでは、このnamespace内の型を短い名前で使います」という宣言です。
2-3. using System; の意味
初心者が最初によく見るのが、次のコードです。
C#using System;
System は、C#や.NETで基本的なクラスが多く含まれているnamespaceです。
たとえば、Console クラスは System namespaceにあります。
そのため、using System; を書くと、次のように短く書けます。
C#using System;
Console.WriteLine("Hello");
もし using System; を書かない場合は、次のように書く必要があります。
C#System.Console.WriteLine("Hello");
どちらも同じ意味ですが、using System; を使うことでコードが読みやすくなります。
2-4. usingを書かない場合のコード例
usingを書かない場合、namespaceを含めた完全修飾名でクラスを指定します。
C#class Program
{
static void Main()
{
System.Console.WriteLine("Hello");
System.DateTime now = System.DateTime.Now;
System.Console.WriteLine(now);
}
}
一方、using System; を書くと次のようになります。
C#using System;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
DateTime now = DateTime.Now;
Console.WriteLine(now);
}
}
どちらも実行結果は同じですが、後者のほうがすっきりしています。
2-5. usingとnamespaceの違い
namespace と using は似ているように見えますが、役割は違います。
namespace は、クラスを分類するための名前です。
C#namespace MyApp.Services
{
public class MailService
{
}
}
一方、using は、別のnamespaceにあるクラスを短く使うための指定です。
C#using MyApp.Services;
MailService service = new MailService();
つまり、namespaceは「クラスが所属する場所」、usingは「その場所を省略して書くための仕組み」です。
初心者向けに言い換えると、namespaceは住所、usingは住所の省略登録のようなものです。
3. usingディレクティブの基本的な使い方
usingディレクティブは、C#のコードで非常によく使われます。
ファイルの先頭に using を書くことで、そのファイル内で指定したnamespaceの型を短く使えるようになります。
3-1. ファイル先頭にusingを書く基本形
基本的な書き方は次のとおりです。
C#using System;
using System.Collections.Generic;
using System.IO;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
List<string> names = new List<string>();
}
}
using は通常、ファイルの先頭にまとめて書きます。
C#using 名前空間;
という形で、最後にセミコロンが必要です。
たとえば、List<T> を使う場合は System.Collections.Generic が必要です。
C#using System.Collections.Generic;
List<int> numbers = new List<int>();
StreamReader を使う場合は System.IO が必要です。
C#using System.IO;
StreamReader reader = new StreamReader("sample.txt");
3-2. よく使うusingの例
C#でよく使われるusingディレクティブには、次のようなものがあります。
C#using System;
Console、DateTime、Math など基本的な型を使うときに使います。
C#using System.Collections.Generic;
List<T>、Dictionary<TKey, TValue> などのコレクションを使うときに使います。
C#using System.IO;
File、StreamReader、FileStream などファイル操作関連のクラスを使うときに使います。
C#using System.Linq;
Where、Select、OrderBy などLINQを使うときに使います。
C#using System.Threading.Tasks;
Task や非同期処理を使うときに使います。
.NETのバージョンやプロジェクトテンプレートによっては、よく使うusingが自動的に有効になっている場合もあります。
3-3. Visual Studioで自動追加されるusing
Visual StudioやVisual Studio Codeでは、存在しない型を入力したときに、必要なusingを自動で追加する候補が表示されることがあります。
たとえば、次のように書いたとします。
C#List<string> names = new List<string>();
List に赤い波線が出ている場合、候補から using System.Collections.Generic; を追加できます。
IDEによっては、ショートカットやクイックアクションで自動追加できます。
ただし、自動追加されたusingが常に正しいとは限りません。似た名前の型が複数のnamespaceに存在する場合、意図しないnamespaceが追加されることもあります。
そのため、エラーが消えたとしても、どのnamespaceが追加されたかは確認しておくと安心です。
3-4. 不要なusingを削除してよいケース
ファイルの先頭に書かれているusingの中には、実際には使われていないものが含まれることがあります。
たとえば、次のコードを見てください。
C#using System;
using System.IO;
using System.Collections.Generic;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
このコードでは Console しか使っていないため、System.IO と System.Collections.Generic は不要です。
不要なusingは削除しても問題ありません。
C#using System;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
不要なusingを削除すると、コードが整理され、どの機能を使っているかがわかりやすくなります。
ただし、学習中は無理に削除しなくても構いません。まずは必要なusingを追加できることを優先しましょう。
3-5. usingを追加してもエラーが消えない原因
usingを追加してもエラーが消えない場合、いくつかの原因が考えられます。
1つ目は、必要なライブラリやパッケージがプロジェクトに参照されていないケースです。
たとえば、NuGetパッケージが必要なクラスを使っている場合、usingを追加するだけでは使えません。先にパッケージのインストールが必要です。
2つ目は、namespaceが間違っているケースです。
C#using System.IO;
と書いても、対象のクラスが System.IO に存在しなければエラーは消えません。
3つ目は、クラス名や型名のスペルミスです。
C#Consol.WriteLine("Hello");
この場合、正しくは Console です。usingを追加しても、型名自体が間違っていればエラーになります。
4つ目は、アクセス修飾子の問題です。
別のプロジェクトやnamespaceにあるクラスでも、public で公開されていなければ外部から使えない場合があります。
usingはあくまで「名前を省略して書けるようにする仕組み」であり、存在しない型を使えるようにしたり、参照されていないライブラリを自動で追加したりするものではありません。
4. Disposeとは?リソース解放が必要な理由
C# usingのもう1つの重要な役割が、Disposeの自動実行です。
Disposeを理解すると、ファイル操作、データベース接続、ネットワーク通信などのコードが安全に書けるようになります。
4-1. Disposeの基本的な意味
Dispose は、使い終わったリソースを明示的に解放するためのメソッドです。
たとえば、ファイルを開いたり、データベースに接続したりすると、プログラムの外側にある資源を使います。
このような資源は、使い終わったらきちんと解放する必要があります。
C#reader.Dispose();
Disposeを呼ぶことで、「このオブジェクトはもう使い終わったので、内部で保持しているリソースを解放してください」と伝えます。
4-2. ファイル・DB接続・ストリームでDisposeが必要な理由
Disposeが特に重要になるのは、次のような処理です。
ファイルを開く処理。
データベース接続。
ネットワーク通信。
ストリーム操作。
画像やハンドルなどOSリソースを扱う処理。
たとえば、ファイルを開いたまま解放しないと、他の処理からそのファイルを編集できなくなることがあります。
データベース接続を閉じないままにすると、接続数が増え続け、最終的に新しい接続が作れなくなる可能性があります。
メモリだけでなく、OSや外部システムのリソースを使う場合は、Disposeによる解放が大切です。
4-3. IDisposableインターフェイスとは
C#では、Disposeが必要な型は通常 IDisposable インターフェイスを実装しています。
C#public interface IDisposable
{
void Dispose();
}
実際には、自分でこのインターフェイスを書くことは少ないですが、考え方としては「Disposeできる型」を表すものです。
たとえば、StreamReader は IDisposable を実装しています。
C#StreamReader reader = new StreamReader("sample.txt");
reader.Dispose();
IDisposable を実装している型は、使い終わったらDisposeする必要があります。
代表的な例として、次のような型があります。
C#StreamReader
FileStream
SqlConnection
HttpClient
Bitmap
ただし、HttpClient のようにアプリケーション全体で使い回すことが推奨されるケースもあります。すべてのIDisposableを短いusingで囲めばよい、というわけではありません。
4-4. Disposeしないと起きる問題
Disposeを忘れると、次のような問題が起きる可能性があります。
ファイルが開きっぱなしになる。
データベース接続が解放されない。
メモリ使用量が増える。
外部リソースが不足する。
処理が遅くなる。
予期しないエラーが発生する。
たとえば、ファイルを読み込むコードでDisposeを忘れると、ファイルがロックされたままになる場合があります。
C#var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
// Disposeを忘れている
このようなコードは、短いサンプルでは問題が見えにくいかもしれません。しかし、実際のアプリケーションではリソース不足や不安定な動作の原因になります。
4-5. GCとDisposeの違い
C#にはGC、つまりガベージコレクションがあります。
GCは、使われなくなったオブジェクトのメモリを自動的に回収する仕組みです。
しかし、GCが回収するのは主にマネージドメモリです。ファイルハンドル、DB接続、ネットワーク接続などの外部リソースは、GCだけに任せるのではなく、Disposeで明示的に解放する必要があります。
GCとDisposeの違いは次のように整理できます。
| 項目 | GC | Dispose |
|---|---|---|
| 目的 | 不要なメモリの回収 | 外部リソースの解放 |
| 実行タイミング | 自動だが不定 | 明示的に呼べる |
| 対象 | 主にメモリ | ファイル、DB接続、ストリームなど |
| 開発者の操作 | 基本的に不要 | 必要な場面がある |
つまり、GCがあるからDisposeは不要、というわけではありません。
リソースをすぐに解放したい場合は、Disposeを使います。
5. usingステートメントとは?Disposeを自動で呼び出す書き方
usingステートメント は、IDisposableを実装したオブジェクトのDisposeを自動で呼び出すための構文です。
ファイル操作やデータベース接続などでよく使われます。
5-1. usingステートメントの基本構文
usingステートメントの基本形は次のとおりです。
C#using (var resource = new SomeDisposableClass())
{
// resourceを使う処理
}
using の丸括弧の中で作成したオブジェクトは、ブロックを抜けるときに自動的にDisposeされます。
たとえば、次のように使います。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
この場合、using ブロックを抜けたタイミングで reader.Dispose() が自動的に呼び出されます。
5-2. 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);
}
}
}
このコードでは、StreamReader を使って sample.txt を読み込んでいます。
StreamReader はファイルを扱うため、使い終わったら閉じる必要があります。
usingステートメントを使うことで、明示的に次のように書かなくても済みます。
C#reader.Dispose();
例外が発生した場合でも、usingブロックを抜けるとDisposeが呼ばれます。
5-3. usingブロックを抜けるとDisposeされる仕組み
usingステートメントのポイントは、ブロックを抜けるとDisposeされることです。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
// ここに来た時点でreaderはDispose済み
ブロックの外では、基本的にそのオブジェクトを使うべきではありません。
Disposeされたオブジェクトを使おうとすると、型によっては ObjectDisposedException が発生することがあります。
C#StreamReader reader;
using (reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadLine());
}
// Dispose後なので使うべきではない
// Console.WriteLine(reader.ReadLine());
usingステートメントは、リソースを使う範囲を明確にするための構文でもあります。
5-4. try-finallyで書いた場合との違い
usingステートメントは、内部的には try-finally に近い動きをします。
usingを使わずに書くと、次のようになります。
C#StreamReader reader = null;
try
{
reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
finally
{
if (reader != null)
{
reader.Dispose();
}
}
usingステートメントを使うと、同じような処理を簡潔に書けます。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
どちらも、処理の途中で例外が発生してもDisposeを呼び出すことができます。
初心者は、Disposeが必要な型を使うときはusingステートメントを使う、と覚えておくとよいでしょう。
5-5. usingステートメントを使うべき場面
usingステートメントを使うべき場面は、主に IDisposable を実装しているオブジェクトを短い範囲で使うときです。
代表例は次のとおりです。
C#using (var stream = new FileStream("sample.txt", FileMode.Open))
{
// ファイル操作
}
C#using (var reader = new StreamReader("sample.txt"))
{
// テキスト読み込み
}
C#using (var connection = new SqlConnection(connectionString))
{
// DB接続
}
usingステートメントを使うと、リソースの解放忘れを防ぎやすくなります。
ただし、アプリケーション全体で長く使い回すオブジェクトに対して、すぐにusingで破棄してよいとは限りません。
「短い処理の中で作成し、その処理が終わったら確実に片付けたいもの」に使うのが基本です。
6. using宣言とは?C# 8.0以降の新しい書き方
C# 8.0以降では、using宣言 という書き方が使えるようになりました。
using宣言もDisposeを自動で呼び出すための構文ですが、usingステートメントよりもコードを簡潔に書けます。
6-1. using宣言の基本構文
using宣言の基本形は次のとおりです。
C#using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
usingステートメントのように波括弧 { } で囲みません。
ただし、reader はスコープを抜けるときに自動でDisposeされます。
メソッド内で使うと、通常はメソッドを抜けるタイミングでDisposeされます。
C#static void ReadFile()
{
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
} // ここでreader.Dispose()が呼ばれる
6-2. usingステートメントとの違い
usingステートメントとusing宣言の違いは、主に書き方とDisposeされるタイミングです。
usingステートメントは、ブロックを抜けるとDisposeされます。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
} // ここでDispose
using宣言は、宣言された変数のスコープを抜けるとDisposeされます。
C#static void Main()
{
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
} // ここでDispose
using宣言は波括弧が減るため、ネストが深くなりにくいというメリットがあります。
6-3. Disposeされるタイミングの違い
Disposeされるタイミングは、usingステートメントとusing宣言で少し異なります。
usingステートメントでは、usingブロックを抜けた時点でDisposeされます。
C#using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadLine());
}
// この時点でDispose済み
using宣言では、その変数が宣言されたスコープを抜けた時点でDisposeされます。
C#static void Main()
{
using var reader = new StreamReader("sample.txt");
Console.WriteLine(reader.ReadLine());
Console.WriteLine("まだ同じスコープ内です");
} // ここでDispose
つまり、using宣言は見た目が短い反面、Disposeのタイミングがusingステートメントより後になる場合があります。
短い範囲で確実にDisposeしたい場合は、usingステートメントのほうがわかりやすいこともあります。
6-4. using宣言を使うメリット
using宣言のメリットは、コードが簡潔になることです。
たとえば、複数のリソースを扱うとき、usingステートメントだけで書くとネストが深くなることがあります。
C#using (var stream = new FileStream("sample.txt", FileMode.Open))
{
using (var reader = new StreamReader(stream))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
}
using宣言を使うと、次のように書けます。
C#using var stream = new FileStream("sample.txt", FileMode.Open);
using var reader = new StreamReader(stream);
string text = reader.ReadToEnd();
Console.WriteLine(text);
ネストが少なくなり、処理の流れが読みやすくなります。
ただし、Disposeのタイミングはスコープの終わりになるため、そこは意識しておく必要があります。
6-5. 初心者はどちらを使うべきか
初心者には、まずusingステートメントから覚えることをおすすめします。
理由は、Disposeされる範囲が波括弧で明確だからです。
C#using (var reader = new StreamReader("sample.txt"))
{
// この中だけreaderを使う
}
この形なら、「このブロックを抜けたらDisposeされる」と視覚的に理解しやすいです。
C#に慣れてきたら、using宣言を使ってコードを簡潔に書くとよいでしょう。
C#using var reader = new StreamReader("sample.txt");
実務ではどちらも使われます。大切なのは、Disposeされるタイミングを理解して使い分けることです。
7. usingの種類と違いを一覧で整理
C#のusingには、いくつかの種類があります。
初心者が最初に理解すべきなのは、usingディレクティブ、usingステートメント、using宣言の3つです。
さらに、少し進んだ使い方として、using static、usingエイリアス、global usingがあります。
7-1. usingディレクティブ
usingディレクティブは、namespaceを省略して書くためのusingです。
C#using System;
using System.Collections.Generic;
using System.IO;
これにより、次のように短く書けます。
C#Console.WriteLine("Hello");
List<string> names = new List<string>();
StreamReader reader = new StreamReader("sample.txt");
usingディレクティブは、主にファイルの先頭に書きます。
C# usingと聞いたとき、初心者が最初に出会うのはこの形が多いです。
7-2. usingステートメント
usingステートメントは、Disposeを自動で呼び出すためのusingです。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
usingブロックを抜けると、reader.Dispose() が自動的に呼ばれます。
ファイル、ストリーム、DB接続など、使い終わったら解放すべきリソースに使います。
7-3. using宣言
using宣言は、C# 8.0以降で使えるDispose自動化の書き方です。
C#using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
usingステートメントよりも短く書けます。
ただし、Disposeされるタイミングは、変数が宣言されたスコープを抜けるときです。
7-4. using static
using static は、staticメンバーをクラス名なしで使えるようにする書き方です。
たとえば、通常は Math.Sqrt のように書きます。
C#double result = Math.Sqrt(16);
using static System.Math; を使うと、次のように書けます。
C#using static System.Math;
double result = Sqrt(16);
Console.WriteLine も、次のように短くできます。
C#using static System.Console;
WriteLine("Hello");
ただし、使いすぎると、どのクラスのメソッドなのかわかりにくくなる場合があります。初心者のうちは、必要な場面だけに限定するのがおすすめです。
7-5. usingエイリアス
usingエイリアスは、型やnamespaceに別名を付ける機能です。
C#using MyList = System.Collections.Generic.List<string>;
MyList names = new MyList();
names.Add("Taro");
また、同じ名前の型が複数のnamespaceに存在する場合にも使えます。
C#using TextBoxWinForms = System.Windows.Forms.TextBox;
using TextBoxWpf = System.Windows.Controls.TextBox;
このように別名を付けることで、名前の衝突を避けられます。
usingエイリアスは初心者が頻繁に使うものではありませんが、大規模なプロジェクトでは役に立つことがあります。
7-6. global using
global using は、C# 10以降で使える機能です。
通常のusingディレクティブは、そのファイル内だけで有効です。
C#using System;
一方、global usingはプロジェクト全体で有効になります。
C#global using System;
global using System.Collections.Generic;
global using System.Linq;
これにより、すべてのファイルに同じusingを何度も書かなくて済みます。
.NET 6以降のプロジェクトでは、暗黙的にglobal usingが有効になっている場合があります。そのため、using System; を書いていないのに Console.WriteLine が使えることがあります。
初心者が「using System; がないのに動くのはなぜ?」と感じた場合、global usingや暗黙的なusingが関係している可能性があります。
7-7. 用途別の使い分け早見表
C# usingの種類を整理すると、次のようになります。
| 種類 | 目的 | 例 |
|---|---|---|
| usingディレクティブ | namespaceを省略する | using System; |
| usingステートメント | ブロック終了時にDisposeする | using (var reader = ...) { } |
| using宣言 | スコープ終了時にDisposeする | using var reader = ...; |
| using static | staticメンバーを短く書く | using static System.Math; |
| usingエイリアス | 型やnamespaceに別名を付ける | using MyList = ...; |
| global using | プロジェクト全体でusingを有効にする | global using System; |
初心者は、まず次の3つを押さえれば十分です。
C#using System;
これはnamespaceを省略するusingです。
C#using (var reader = new StreamReader("sample.txt"))
{
}
これはDisposeを自動で呼び出すusingステートメントです。
C#using var reader = new StreamReader("sample.txt");
これはC# 8.0以降のusing宣言です。
8. usingでよくあるエラーと対処法
C# usingを使っていると、初心者がつまずきやすいエラーがいくつかあります。
ここでは、よくある原因と対処法を整理します。
8-1. 型または名前空間の名前が見つからない
よくあるエラーの1つが、次のようなものです。
型または名前空間の名前 'List' が見つかりません
たとえば、次のコードでは List を使っています。
C#List<string> names = new List<string>();
このとき、System.Collections.Generic をusingしていないとエラーになります。
C#using System.Collections.Generic;
修正後は次のようになります。
C#using System.Collections.Generic;
List<string> names = new List<string>();
ただし、usingを追加しても解決しない場合は、型名のスペルミスや参照設定の不足も確認しましょう。
8-2. usingを追加しても参照できない
usingを追加しても型を参照できない場合、次の原因が考えられます。
必要なNuGetパッケージが入っていない。
プロジェクト参照が追加されていない。
対象のクラスが public ではない。
namespaceが間違っている。
ターゲットフレームワークが対応していない。
たとえば、外部ライブラリのクラスを使う場合、usingを書くだけでは不十分です。
C#using SomeLibrary;
このように書いても、そもそも SomeLibrary がプロジェクトにインストールされていなければエラーになります。
usingはライブラリを追加する機能ではありません。あくまで、すでに参照できるnamespaceを短く書くための機能です。
8-3. IDisposableではない型にusingを使っている
usingステートメントやusing宣言は、基本的に IDisposable を実装している型に対して使います。
たとえば、次のようなコードはエラーになります。
C#using (var text = "Hello")
{
Console.WriteLine(text);
}
string は IDisposable を実装していないため、usingで囲む必要はありません。
usingステートメントを使えるかどうかは、その型がDisposeできるかどうかで決まります。
正しい例は次のようなものです。
C#using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
StreamReader は IDisposable を実装しているため、usingステートメントで使えます。
8-4. Dispose後のオブジェクトを使ってしまう
usingステートメントを抜けた後に、そのオブジェクトを使おうとすると問題が起きます。
C#StreamReader reader;
using (reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadLine());
}
// usingブロックを抜けた後なのでreaderはDispose済み
Console.WriteLine(reader.ReadLine());
このようなコードでは、Dispose済みの reader を使っているため、例外が発生する可能性があります。
usingで囲んだオブジェクトは、そのブロック内だけで使うのが基本です。
C#using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadLine());
}
このように、変数をusingブロック内で宣言すれば、ブロックの外から誤って使うことを防げます。
8-5. namespaceの競合が起きる
同じ名前の型が複数のnamespaceに存在すると、名前の競合が起きる場合があります。
たとえば、2つのnamespaceに同じ User クラスがあるとします。
C#using App.Models;
using App.Entities;
User user = new User();
この場合、どちらの User を使うべきかわからず、コンパイルエラーになることがあります。
対処法の1つは、完全修飾名を書くことです。
C#App.Models.User user = new App.Models.User();
もう1つは、usingエイリアスを使うことです。
C#using ModelUser = App.Models.User;
using EntityUser = App.Entities.User;
ModelUser user1 = new ModelUser();
EntityUser user2 = new EntityUser();
名前の競合が起きたときは、usingを増やすのではなく、どの型を使いたいのかを明確にすることが大切です。
9. C# usingの実践コード例
ここからは、C# usingの具体的なコード例を見ていきます。
namespaceの省略、Disposeの自動化、using宣言、完全修飾名など、実際によく使うパターンを確認しましょう。
9-1. Console.WriteLineとusing Systemの例
まずは、もっとも基本的な using System; の例です。
C#using System;
class Program
{
static void Main()
{
Console.WriteLine("Hello, C#");
}
}
Console クラスは System namespaceにあります。
そのため、using System; を書くことで、System.Console と書かずに済みます。
usingを書かない場合は、次のようになります。
C#class Program
{
static void Main()
{
System.Console.WriteLine("Hello, C#");
}
}
どちらも同じ処理ですが、usingを使ったほうが読みやすくなります。
9-2. StreamReaderで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);
}
}
}
このコードでは、StreamReader を使ってファイルの内容を読み込んでいます。
StreamReader はIDisposableを実装しているため、使い終わったらDisposeする必要があります。
usingステートメントを使えば、ブロックを抜けたときに自動でDisposeされます。
9-3. SqlConnectionでDisposeを自動化する例
データベース接続でもusingステートメントはよく使われます。
C#using System;
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = "接続文字列をここに書く";
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);
}
}
}
}
この例では、SqlConnection と command をusingステートメントで囲んでいます。
データベース接続は使い終わったら解放する必要があるため、usingステートメントと相性が良いです。
ただし、実際のアプリケーションでは接続文字列の管理や例外処理、非同期処理なども考慮する必要があります。
9-4. using宣言でコードを簡潔にする例
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);
}
}
usingステートメントで書くと次のようになります。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
using宣言では波括弧が不要になるため、コードがすっきりします。
ただし、Disposeされるのはスコープの終わりです。上の例では、Main メソッドを抜けるときに reader.Dispose() が呼ばれます。
9-5. namespaceを完全修飾名で書く例
usingディレクティブを使わず、完全修飾名で書くこともできます。
C#class Program
{
static void Main()
{
System.Console.WriteLine("Hello");
System.Collections.Generic.List<string> names =
new System.Collections.Generic.List<string>();
names.Add("Taro");
System.Console.WriteLine(names[0]);
}
}
このコードでは、System.Console や System.Collections.Generic.List<string> のように、namespaceをすべて書いています。
usingディレクティブを使うと、次のように短くできます。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
List<string> names = new List<string>();
names.Add("Taro");
Console.WriteLine(names[0]);
}
}
完全修飾名は長くなりますが、どのnamespaceの型を使っているかを明確にできます。
名前の競合が起きたときや、一時的に型の所属を確認したいときに役立ちます。
まとめ
C#の using には複数の意味があります。
初心者がまず理解すべきなのは、「namespaceを省略するusing」と「Disposeを自動で呼び出すusing」です。
C#using System;
これはusingディレクティブです。namespaceを省略して、Console や DateTime などの型を短く書けるようにします。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}
これはusingステートメントです。ブロックを抜けると、Disposeが自動的に呼び出されます。
C#using var reader = new StreamReader("sample.txt");
これはusing宣言です。C# 8.0以降で使える書き方で、スコープを抜けるとDisposeされます。
usingとnamespaceの違いも重要です。
namespaceは、クラスが所属する場所です。
usingは、そのnamespaceを省略して書くための仕組みです。
また、Disposeはファイル、DB接続、ストリームなどのリソースを解放するために必要です。GCがあるからDisposeが不要になるわけではありません。
C# usingで迷ったときは、まず次のように考えると整理しやすくなります。
ファイルの先頭にある using System; は、namespaceを省略するためのusing。
メソッド内で using (...) { } と書くものは、Disposeを自動で呼ぶためのusing。
using var は、C# 8.0以降の簡潔なDispose用のusing。
この3つを理解できれば、C#のusingでつまずく場面はかなり減ります。慣れてきたら、using static、usingエイリアス、global usingも少しずつ覚えていきましょう。

