C# usingとは?namespaceの読み込みからリソース解放まで初心者向けにわかりやすく解説
はじめに
C#を学び始めると、かなり早い段階で using というキーワードに出会います。
たとえば、C#のコードの先頭に次のような記述を見たことがある人は多いでしょう。
C#using System;
一方で、ファイルを開く処理などでは、次のような形でも using が登場します。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}
同じ using というキーワードなのに、書く場所も役割も違うため、初心者にとっては混乱しやすいポイントです。
C# usingとは何かを理解するには、まず using には大きく分けて2つの意味があることを押さえる必要があります。
1つ目は、namespace を読み込んでクラス名を短く書けるようにする usingディレクティブ です。
2つ目は、ファイルやデータベース接続などのリソースを使い終わったあとに自動で解放する usingステートメント や using宣言 です。
この記事では、C#の using について、namespaceの読み込みからリソース解放まで、初心者にもわかりやすく順番に解説します。
1. C#のusingとは?初心者がまず押さえる基本
C#の using は、文脈によって役割が変わるキーワードです。
コードの先頭に書かれている using と、処理の中でリソースを囲むように書かれている using は、同じ単語でも目的が異なります。
初心者が最初に混乱しやすいのは、「usingはnamespaceを読み込むもの」と覚えたあとに、「usingはリソースを解放するもの」と説明されることです。
どちらも正しい説明ですが、使われる場面が違います。
1-1. usingには「namespaceの読み込み」と「リソース解放」の2つの意味がある
C#の using には、主に次の2つの意味があります。
C#using System;
このようにファイルの先頭などに書く using は、usingディレクティブ と呼ばれます。
これは System というnamespaceを読み込み、System.Console を Console のように短く書けるようにするためのものです。
一方、次のような using は、リソースを自動で解放するために使います。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}
これは usingステートメント と呼ばれます。
ファイル、ネットワーク接続、データベース接続などは、使い終わったあとに適切に閉じる必要があります。usingステートメント を使うと、処理が終わったタイミングで自動的に Dispose が呼ばれ、リソースが解放されます。
つまり、C# usingとは大きく分けると、次の2つを指します。
namespaceを読み込むusing と、リソースを解放するusing です。
1-2. なぜ同じusingなのに使い方が違うのか
C#では、同じキーワードが文脈によって異なる意味を持つことがあります。
using もその1つです。
ファイルの先頭やnamespaceの外側に書かれている場合は、基本的に usingディレクティブ として解釈されます。
C#using System;
using System.Collections.Generic;
一方、メソッドの中などでオブジェクトを囲むように書かれている場合は、usingステートメント として解釈されます。
C#using (var stream = new FileStream("sample.txt", FileMode.Open))
{
// ファイルを使う処理
}
また、C# 8.0以降では、次のような using宣言 も使えるようになりました。
C#using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
このように、using は書く場所や構文によって意味が変わります。
初心者のうちは、「usingは1種類だけではない」と考えると理解しやすくなります。
1-3. この記事で理解できるusingの全体像
この記事では、C#の using について次の順番で解説します。
まず、using System; のような usingディレクティブ について説明します。
次に、ファイル操作などで使う usingステートメント について解説します。
さらに、C# 8.0以降で使える using宣言 や、using static、usingエイリアス、global using、暗黙的なusingについても紹介します。
最後に、初心者がつまずきやすいエラーや対処法も解説します。
C# usingとは何かを体系的に理解したい場合は、まず「namespaceのusing」と「リソース解放のusing」を分けて考えることが重要です。
2. usingディレクティブとは?namespaceを読み込む書き方
usingディレクティブ は、指定したnamespaceに含まれる型を、短い名前で使えるようにするための機能です。
C#のコードでよく見る次のような記述が、usingディレクティブです。
C#using System;
これは、System というnamespaceを使うことを宣言しています。
2-1. using System; の意味
using System; は、System namespaceに含まれる型を、完全修飾名ではなく短い名前で使えるようにするための記述です。
たとえば、画面に文字を表示するときによく使う Console.WriteLine は、正確には System.Console.WriteLine と書くこともできます。
using System; がある場合は、次のように短く書けます。
C#using System;
Console.WriteLine("こんにちは");
using System; がない場合は、次のように書く必要があります。
C#System.Console.WriteLine("こんにちは");
どちらも同じ処理ですが、毎回 System. と書くのは面倒です。
そこで using System; を書くことで、コードを簡潔にできます。
2-2. namespaceとは何か
namespaceとは、クラスやインターフェースなどを整理するための名前のまとまりです。
C#には多くのクラスが用意されています。たとえば、文字を表示する Console、リストを扱う List<T>、ファイルを扱う File や StreamReader などがあります。
これらの型をすべて同じ場所に置くと、名前の衝突が起きやすくなります。
そこで、関連する型をnamespaceごとに分類します。
たとえば、代表的なnamespaceには次のようなものがあります。
C#System
System.Collections.Generic
System.IO
System.Linq
System.Threading.Tasks
Console は System namespaceに含まれています。
List<T> は System.Collections.Generic namespaceに含まれています。
File や StreamReader は System.IO namespaceに含まれています。
つまり、namespaceは「型の住所」のようなものです。
using は、その住所をあらかじめ指定しておくことで、型名を短く書けるようにする仕組みです。
2-3. usingを書かない場合は完全修飾名が必要になる
usingディレクティブを書かない場合、その型がどのnamespaceにあるのかを完全に指定する必要があります。
これを完全修飾名といいます。
たとえば、List<int> を使いたい場合、通常は次のように書きます。
C#using System.Collections.Generic;
List<int> numbers = new List<int>();
しかし、using System.Collections.Generic; を書かない場合は、次のように完全修飾名で書く必要があります。
C#System.Collections.Generic.List<int> numbers = new System.Collections.Generic.List<int>();
動作は同じですが、コードが長く読みにくくなります。
そのため、よく使うnamespaceはusingディレクティブで読み込むのが一般的です。
2-4. usingディレクティブの基本構文
usingディレクティブの基本構文は次のとおりです。
C#using 名前空間名;
たとえば、次のように書きます。
C#using System;
using System.Collections.Generic;
using System.IO;
それぞれの意味は次のとおりです。
C#using System; // Consoleなどを使いやすくする
using System.Collections.Generic; // List<T>などを使いやすくする
using System.IO; // FileやStreamReaderなどを使いやすくする
usingディレクティブは、あくまで型名を短く書くためのものです。
ライブラリそのものをインストールしたり、プロジェクトに参照を追加したりする機能ではありません。
この点は初心者が誤解しやすいので注意が必要です。
2-5. usingはどこに書くのが正しいのか
usingディレクティブは、一般的にはC#ファイルの先頭に書きます。
C#using System;
using System.Collections.Generic;
namespace SampleApp
{
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
}
C#では、namespaceの内側にusingを書くこともできます。
C#namespace SampleApp
{
using System;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
}
ただし、初心者のうちは、ファイルの先頭にまとめて書く方法を覚えておけば問題ありません。
また、C# 10以降では global using という機能もあり、プロジェクト全体に対してusingを有効にすることもできます。
ただし、まずは通常の using System; のようなusingディレクティブを理解することが大切です。
3. usingディレクティブの具体例
ここからは、usingディレクティブの具体例を見ていきます。
using がある場合とない場合を比較すると、役割がよりわかりやすくなります。
3-1. Console.WriteLineでusing Systemを使う例
C#で文字を表示するときによく使うのが Console.WriteLine です。
C#using System;
class Program
{
static void Main()
{
Console.WriteLine("C# usingとは何かを学びます");
}
}
このコードでは、using System; を書いているため、Console.WriteLine と短く書けます。
もし using System; を書かない場合は、次のように書く必要があります。
C#class Program
{
static void Main()
{
System.Console.WriteLine("C# usingとは何かを学びます");
}
}
どちらも実行結果は同じですが、using System; を使ったほうが読みやすくなります。
3-2. Listを使うためのusing System.Collections.Generic
C#で複数の値を扱うときによく使うのが List<T> です。
List<T> を使うには、通常 System.Collections.Generic namespaceをusingします。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<string> names = new List<string>();
names.Add("佐藤");
names.Add("鈴木");
names.Add("田中");
foreach (string name in names)
{
Console.WriteLine(name);
}
}
}
using System.Collections.Generic; があることで、List<string> と短く書けます。
usingを書かない場合は、次のように長い名前になります。
C#System.Collections.Generic.List<string> names =
new System.Collections.Generic.List<string>();
このように、usingディレクティブはコードを簡潔にするために役立ちます。
3-3. ファイル操作で使うusing System.IO
ファイルを読み書きするときには、System.IO namespaceを使うことが多いです。
たとえば、テキストファイルの内容を読み込む場合は、次のように書けます。
C#using System;
using System.IO;
class Program
{
static void Main()
{
string text = File.ReadAllText("sample.txt");
Console.WriteLine(text);
}
}
ここでは、File クラスを使っています。
File クラスは System.IO namespaceに含まれているため、using System.IO; を書くことで File.ReadAllText と短く書けます。
usingを書かない場合は、次のようになります。
C#string text = System.IO.File.ReadAllText("sample.txt");
ファイル操作では File、FileStream、StreamReader、StreamWriter などを使うことが多いため、using System.IO; はよく登場します。
3-4. Visual StudioやIDEでusingが自動追加される仕組み
Visual StudioやVisual Studio CodeなどのIDEでは、必要なusingを自動で追加してくれる機能があります。
たとえば、List<string> と書いたときに System.Collections.Generic が読み込まれていない場合、IDEがエラーを表示し、候補として using System.Collections.Generic; の追加を提案してくれます。
また、不要になったusingを削除する機能もあります。
C#using System;
using System.Collections.Generic;
using System.IO;
この中で System.IO を使っていない場合、IDEが「usingディレクティブは不要です」と表示することがあります。
これはエラーではなく、コードを整理するための警告や提案です。
初心者のうちは、IDEの自動修正を活用しながら、どの型がどのnamespaceに含まれているのかを少しずつ覚えていくとよいでしょう。
4. usingステートメントとは?リソースを自動で解放する仕組み
C#の using には、namespaceを読み込む以外に、リソースを自動で解放する役割もあります。
これが usingステートメント です。
ファイル、データベース接続、ネットワーク接続などは、使い終わったあとに適切に閉じる必要があります。
閉じ忘れると、ファイルがロックされたままになったり、メモリや接続が無駄に残ったりすることがあります。
usingステートメントを使うと、処理が終わったタイミングで自動的にリソースを解放できます。
4-1. usingステートメントの役割
usingステートメントは、使い終わったら必ず解放すべきオブジェクトを安全に扱うための構文です。
基本的な書き方は次のとおりです。
C#using (リソースを作成する式)
{
// リソースを使う処理
}
たとえば、ファイルを読み込む場合は次のように書きます。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
このコードでは、using ブロックの中で reader を使っています。
ブロックを抜けると、自動的に reader.Dispose() が呼ばれます。
そのため、明示的に reader.Close() や reader.Dispose() を書かなくても、ファイルが適切に閉じられます。
4-2. Disposeとは何か
Dispose とは、使い終わったリソースを解放するためのメソッドです。
C#では、メモリ管理はガベージコレクションによって自動的に行われます。
しかし、ファイルハンドル、データベース接続、ネットワーク接続など、メモリ以外のリソースは、できるだけ早く明示的に解放したほうがよい場合があります。
そのために使われるのが Dispose です。
たとえば、次のように書くこともできます。
C#var reader = new StreamReader("sample.txt");
try
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
finally
{
reader.Dispose();
}
このコードでは、finally ブロックで Dispose を呼び出しています。
ただし、毎回このように書くのは面倒です。
そこで、usingステートメントを使うと、同じような処理を簡潔に書けます。
4-3. IDisposableインターフェースとは
usingステートメントで扱える型は、基本的に IDisposable インターフェースを実装している型です。
IDisposable は、Dispose メソッドを持つことを表すインターフェースです。
簡略化すると、次のような形です。
C#public interface IDisposable
{
void Dispose();
}
StreamReader、FileStream、StreamWriter、SqlConnection など、多くのリソース管理系のクラスは IDisposable を実装しています。
そのため、usingステートメントで扱うことができます。
C#using (var stream = new FileStream("sample.txt", FileMode.Open))
{
// streamを使う処理
}
反対に、IDisposable を実装していない型には、usingステートメントを使えません。
たとえば、単なる string や int などにusingステートメントを使うことはできません。
4-4. usingを使うとtry-finallyを書かずに済む理由
usingステートメントは、内部的には try-finally に近い仕組みで動作します。
たとえば、次のusingステートメントがあるとします。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
これは、イメージとしては次のようなコードに近いです。
C#var reader = new StreamReader("sample.txt");
try
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
finally
{
if (reader != null)
{
reader.Dispose();
}
}
つまり、usingステートメントを使うと、リソース解放のための try-finally を自分で書かなくても済みます。
コードが短くなり、解放忘れも防ぎやすくなります。
4-5. 例外が発生してもリソース解放される仕組み
usingステートメントの大きなメリットは、例外が発生しても Dispose が呼ばれることです。
たとえば、次のコードを見てください。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
throw new Exception("途中でエラーが発生しました");
}
このコードでは、usingブロックの途中で例外が発生しています。
それでも、usingブロックを抜けるときに Dispose が呼ばれます。
つまり、正常終了した場合だけでなく、エラーが発生した場合でもリソースが解放されます。
ファイルやデータベース接続などを安全に扱ううえで、usingステートメントは非常に重要です。
5. usingステートメントの使い方をコードで解説
ここからは、usingステートメントの使い方を具体的なコードで確認していきます。
特にファイル操作では、usingステートメントがよく使われます。
5-1. ファイルを読み込む基本例
テキストファイルを読み込む基本的な例を見てみましょう。
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ステートメントを使っているため、ブロックを抜けたタイミングで自動的に Dispose が呼ばれ、ファイルが閉じられます。
5-2. StreamReaderやFileStreamでusingを使う例
StreamReader だけでなく、FileStream でもusingステートメントはよく使われます。
C#using System;
using System.IO;
class Program
{
static void Main()
{
using (var stream = new FileStream("sample.txt", FileMode.Open))
using (var reader = new StreamReader(stream))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
}
}
このコードでは、まず FileStream でファイルを開き、そのストリームを StreamReader に渡しています。
FileStream も StreamReader もリソースを持つため、どちらもusingで管理しています。
usingを複数使うことで、複数のリソースを安全に解放できます。
5-3. usingを使わない場合に起きる問題
usingを使わずにファイルを開いた場合、閉じ忘れが発生する可能性があります。
C#var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
// CloseやDisposeを呼び忘れている
このようなコードでは、ファイルがすぐに解放されない可能性があります。
その結果、別の処理で同じファイルを開こうとしたときに、ファイルが使用中になってエラーが発生することがあります。
また、データベース接続などでは、接続を閉じ忘れると接続数が増え続け、アプリケーション全体の動作に影響する可能性があります。
もちろん、ガベージコレクションによって最終的に解放される場合もあります。
しかし、いつ解放されるかは明確ではありません。
そのため、使い終わったタイミングで確実に解放したいリソースにはusingを使うのが基本です。
5-4. CloseとDisposeの違い
ファイル操作では、Close と Dispose の違いが気になることがあります。
Close は、ファイルや接続などを閉じるためのメソッドです。
Dispose は、リソースを解放するためのより一般的なメソッドです。
多くのクラスでは、Close を呼ぶと内部的に Dispose と同じような処理が行われることがあります。
たとえば、次のように書くこともできます。
C#var reader = new StreamReader("sample.txt");
try
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
finally
{
reader.Close();
}
しかし、C#では IDisposable を実装している型に対しては、usingを使って Dispose に任せる書き方が一般的です。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
初心者のうちは、「Closeを手動で呼ぶより、usingでDisposeを自動的に呼ぶ」と覚えるとよいでしょう。
5-5. 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);
}
この書き方では、stream と reader の両方がusingブロックの終了時に解放されます。
コードがすっきりするため、複数のリソースを扱うときによく使われます。
6. using宣言とは?C# 8.0以降の新しい書き方
C# 8.0以降では、using宣言 という新しい書き方が使えるようになりました。
using宣言を使うと、usingステートメントのように波かっこでブロックを作らなくても、リソースを自動で解放できます。
6-1. using宣言の基本構文
using宣言の基本構文は次のとおりです。
C#using var 変数名 = new リソース型();
たとえば、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);
}
}
このコードでは、reader は Main メソッドのスコープを抜けるときに自動で Dispose されます。
usingステートメントのように、明示的なブロックを書く必要がありません。
6-2. usingステートメントとの違い
usingステートメントは、波かっこで囲まれたブロックを抜けるタイミングで Dispose されます。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
// ここでreaderは使えない
一方、using宣言では、変数が宣言されたスコープを抜けるタイミングで Dispose されます。
C#using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
// 同じスコープ内ではreaderを使える
つまり、usingステートメントは「ブロックの終わり」で解放され、using宣言は「スコープの終わり」で解放されます。
この違いを理解しておくことが大切です。
6-3. スコープを抜けたタイミングでDisposeされる仕組み
using宣言では、変数が宣言されたスコープを抜けるときに Dispose が呼ばれます。
たとえば、次のコードを見てください。
C#static void ReadFile()
{
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
// ReadFileメソッドを抜けるときにreader.Dispose()が呼ばれる
この場合、reader は ReadFile メソッドの中で宣言されています。
そのため、ReadFile メソッドが終了するときに Dispose されます。
using宣言は見た目がシンプルですが、どこでDisposeされるのかを意識しないと、リソースを必要以上に長く保持してしまうことがあります。
6-4. using宣言を使うとコードがシンプルになる例
using宣言を使うと、ネストを減らせます。
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);
処理の流れが一直線になり、読みやすくなる場合があります。
特に、複数のリソースを扱う場合は、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ステートメントのほうがわかりやすいこともあります。
6-5. 初心者はusingステートメントとusing宣言のどちらを使うべきか
初心者は、まずusingステートメントから覚えるのがおすすめです。
理由は、usingステートメントのほうがリソースの有効範囲が見た目でわかりやすいからです。
C#using (var reader = new StreamReader("sample.txt"))
{
// この中だけreaderを使う
}
このように、波かっこの中だけでリソースを使うことが明確です。
一方、using宣言はコードがシンプルになる反面、Disposeされるタイミングがスコープの終わりになるため、慣れていないと少しわかりにくい場合があります。
実務ではusing宣言もよく使われますが、最初はusingステートメントで仕組みを理解し、そのあとにusing宣言を覚えるとよいでしょう。
7. usingの応用機能
C#のusingには、基本的なusingディレクティブやusingステートメント以外にも、いくつかの応用機能があります。
ここでは、using static、usingエイリアス、global using、暗黙的なusingについて解説します。
7-1. using staticとは
using static は、指定した型の静的メンバーを、型名なしで使えるようにする機能です。
たとえば、通常 Math.Sqrt のように書く処理があります。
C#double result = Math.Sqrt(16);
using static System.Math; を使うと、次のように Math. を省略できます。
C#using static System.Math;
double result = Sqrt(16);
また、Console.WriteLine も次のように書けます。
C#using static System.Console;
WriteLine("Hello");
ただし、using static を多用すると、どの型のメソッドを呼んでいるのかがわかりにくくなる場合があります。
初心者のうちは、通常の Console.WriteLine や Math.Sqrt の書き方に慣れてから使うとよいでしょう。
7-2. usingエイリアスとは
usingエイリアスは、型やnamespaceに別名を付ける機能です。
基本構文は次のとおりです。
C#using 別名 = 完全修飾名;
たとえば、長い型名に短い別名を付けることができます。
C#using MyList = System.Collections.Generic.List<string>;
class Program
{
static void Main()
{
MyList names = new MyList();
names.Add("佐藤");
}
}
また、同じ名前の型が複数のnamespaceに存在する場合にも役立ちます。
たとえば、System.Timers.Timer と System.Threading.Timer のように、同じ Timer という名前の型が複数ある場合、エイリアスを使うと区別しやすくなります。
C#using TimersTimer = System.Timers.Timer;
using ThreadingTimer = System.Threading.Timer;
名前の競合が起きたときや、長い型名を短くしたいときに便利です。
7-3. global usingとは
global using は、C# 10以降で使える機能です。
通常のusingディレクティブは、そのファイル内でのみ有効です。
C#using System;
一方、global using を使うと、プロジェクト全体でusingを有効にできます。
C#global using System;
global using System.Collections.Generic;
global using System.Linq;
これにより、すべてのC#ファイルに同じusingを書く必要がなくなります。
よく使うnamespaceをプロジェクト全体で共有したい場合に便利です。
ただし、どこでusingされているのか見えにくくなる場合もあるため、プロジェクトの方針に合わせて使うことが大切です。
7-4. 暗黙的なusingとは
.NET 6以降のプロジェクトでは、暗黙的なusingが有効になっていることがあります。
暗黙的なusingとは、よく使うnamespaceを自動的にusingしてくれる機能です。
たとえば、コンソールアプリでは、System などのnamespaceが自動的に読み込まれることがあります。
そのため、コードに using System; が見当たらなくても、Console.WriteLine が使える場合があります。
C#Console.WriteLine("Hello");
これは、プロジェクトファイルで暗黙的なusingが有効になっているためです。
.csproj ファイルに次のような設定がある場合があります。
XML<ImplicitUsings>enable</ImplicitUsings>
この設定が有効だと、プロジェクトの種類に応じて、よく使うnamespaceが自動で追加されます。
7-5. .NET 6以降でusingが見えない理由
.NET 6以降のテンプレートで作成したプロジェクトでは、コードの先頭に using System; がなくても Console.WriteLine が使えることがあります。
また、class Program や static void Main が見えない場合もあります。
これは、暗黙的なusingやトップレベルステートメントといった機能が使われているためです。
たとえば、次のような短いコードだけでコンソールアプリが動きます。
C#Console.WriteLine("Hello, World!");
昔のC#では、次のように書くのが一般的でした。
C#using System;
class Program
{
static void Main()
{
Console.WriteLine("Hello, World!");
}
}
.NET 6以降では、初心者向けにコードが簡潔になるよう、テンプレートが変わっています。
そのため、「usingが見えないのにConsoleが使える」という状況が起きます。
ただし、内部的にusingが不要になったわけではなく、プロジェクト設定によって自動的に補われていると考えると理解しやすいです。
8. C# usingで初心者が混乱しやすいポイント
C# usingとは何かを学ぶうえで、初心者が混乱しやすいポイントがいくつかあります。
ここでは、よくある誤解を整理します。
8-1. namespaceのusingとリソース解放のusingは別物
最も重要なのは、namespaceのusingとリソース解放のusingを分けて考えることです。
次のusingは、namespaceを読み込むためのusingです。
C#using System;
using System.IO;
次のusingは、リソースを自動解放するためのusingです。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}
同じ using というキーワードですが、目的が異なります。
初心者のうちは、次のように覚えるとわかりやすいです。
ファイルの先頭に書くusingは、型名を短くするためのusingです。
メソッドの中でリソースを囲むusingは、使い終わったあとに解放するためのusingです。
8-2. usingを書いてもライブラリ参照が追加されるわけではない
usingディレクティブは、namespaceを短く書けるようにするだけです。
外部ライブラリをプロジェクトに追加する機能ではありません。
たとえば、あるNuGetパッケージのクラスを使いたい場合、まずそのパッケージをプロジェクトに追加する必要があります。
そのうえで、必要なnamespaceをusingします。
C#using SomeLibrary;
もしライブラリ自体がプロジェクトに追加されていなければ、usingを書いてもエラーは解決しません。
usingは「すでに参照できる状態にある型を短く書くためのもの」と考えるとよいでしょう。
8-3. usingしているのにエラーが消えない原因
usingを書いているのにエラーが消えない場合、いくつかの原因が考えられます。
まず、namespace名が間違っている可能性があります。
C#using System.Collection.Generic; // 誤り
正しくは次のように書きます。
C#using System.Collections.Generic;
また、必要なライブラリやNuGetパッケージがプロジェクトに追加されていない場合もあります。
さらに、使いたい型が別のアセンブリに含まれている場合、プロジェクト参照が必要なこともあります。
usingはあくまで名前空間を省略するためのものなので、参照そのものが不足している場合は、usingだけでは解決できません。
8-4. Disposeできない型にはusingステートメントを使えない
usingステートメントやusing宣言は、基本的に IDisposable を実装している型に対して使います。
たとえば、次のようなコードは使えません。
C#using (string text = "Hello")
{
Console.WriteLine(text);
}
string は IDisposable を実装していないため、usingステートメントで管理する対象ではありません。
usingステートメントは、ファイル、ストリーム、データベース接続など、使い終わったあとに明示的な解放が必要なオブジェクトに使います。
すべてのオブジェクトにusingを付ければよいわけではありません。
8-5. 不要なusingは削除してもよいのか
使っていないusingディレクティブは、基本的に削除して問題ありません。
たとえば、次のコードで System.IO を使っていない場合、using System.IO; は不要です。
C#using System;
using System.IO;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
この場合、次のように整理できます。
C#using System;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
不要なusingが残っていても、通常はプログラムの動作に大きな問題はありません。
しかし、コードを読みやすく保つためには、不要なusingを削除するのが望ましいです。
IDEの「不要なusingを削除」機能を使うと簡単に整理できます。
9. usingに関するよくあるエラーと対処法
ここでは、C#のusingに関する代表的なエラーと、その対処法を解説します。
usingに関するエラーは、namespaceの指定ミス、参照不足、IDisposableの理解不足などが原因で起こることが多いです。
9-1. 型または名前空間の名前が見つかりません
よくあるエラーの1つが、次のような内容です。
型または名前空間の名前が見つかりません
これは、指定した型やnamespaceをコンパイラが見つけられないときに発生します。
原因としては、次のようなものがあります。
必要なusingが書かれていない場合。
C#List<int> numbers = new List<int>();
このコードでエラーになる場合は、次のusingを追加します。
C#using System.Collections.Generic;
また、namespace名を間違えている場合もあります。
C#using System.Collection.Generic; // 誤り
正しくは次のとおりです。
C#using System.Collections.Generic;
さらに、外部ライブラリを使っている場合は、NuGetパッケージやプロジェクト参照が追加されているか確認しましょう。
9-2. IDisposableに暗黙的に変換できません
usingステートメントを使ったときに、次のようなエラーが出ることがあります。
型を System.IDisposable に暗黙的に変換できません
これは、usingステートメントで扱おうとしている型が IDisposable を実装していない場合に発生します。
たとえば、次のようなコードです。
C#using (var text = "Hello")
{
Console.WriteLine(text);
}
string は IDisposable を実装していないため、usingステートメントでは使えません。
usingステートメントを使えるのは、基本的に Dispose が必要な型です。
たとえば、次のような型です。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}
エラーが出た場合は、その型が IDisposable を実装しているか確認しましょう。
9-3. usingディレクティブが不要です
IDEやコンパイラの分析機能によって、次のような警告が表示されることがあります。
using ディレクティブは不要です
これは、そのファイル内で指定したnamespaceが使われていないという意味です。
たとえば、次のコードでは System.IO は使われていません。
C#using System;
using System.IO;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
この場合、using System.IO; は削除して問題ありません。
C#using System;
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
この警告は、プログラムが動かないという意味ではありません。
コードを整理するための提案と考えればよいでしょう。
9-4. 名前空間の競合が起きたときの対処法
複数のnamespaceに同じ名前の型が存在する場合、名前の競合が起きることがあります。
たとえば、Timer という型は複数のnamespaceに存在します。
C#using System.Timers;
using System.Threading;
この状態で Timer とだけ書くと、どちらのTimerを使うのか曖昧になる場合があります。
このようなときは、完全修飾名で書く方法があります。
C#System.Timers.Timer timer = new System.Timers.Timer();
また、usingエイリアスを使う方法もあります。
C#using TimersTimer = System.Timers.Timer;
TimersTimer timer = new TimersTimer();
usingエイリアスを使うと、名前の競合を避けながら読みやすいコードにできます。
9-5. NuGetパッケージを追加してもusingが必要な理由
NuGetパッケージを追加すると、そのライブラリの型をプロジェクトから参照できるようになります。
しかし、それだけで型名を短く書けるようになるとは限りません。
たとえば、あるライブラリをNuGetで追加したあと、そのライブラリのクラスを使うには、対応するnamespaceをusingする必要があります。
C#using SomeLibrary;
NuGetパッケージの追加は、ライブラリをプロジェクトで使えるようにする作業です。
usingディレクティブは、そのライブラリ内の型を短い名前で書けるようにする作業です。
つまり、役割が違います。
NuGetを追加したのに型が見つからない場合は、次の点を確認しましょう。
パッケージが正しくインストールされているか。
プロジェクトがそのパッケージを参照しているか。
正しいnamespaceをusingしているか。
対象の型名を間違えていないか。
このように、NuGetとusingはセットで考えることが多いですが、同じ機能ではありません。
まとめ
C# usingとは、文脈によって意味が変わる重要なキーワードです。
まず、using System; のようにファイルの先頭に書くusingは、usingディレクティブ です。
これはnamespaceを読み込み、System.Console を Console のように短く書けるようにするために使います。
C#using System;
Console.WriteLine("Hello");
次に、メソッドの中で使うusingステートメントは、リソースを自動で解放するために使います。
C#using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}
usingステートメントを使うと、ブロックを抜けたときに自動で Dispose が呼ばれます。
そのため、ファイルやデータベース接続などを安全に扱えます。
また、C# 8.0以降では、using宣言という書き方も使えます。
C#using var reader = new StreamReader("sample.txt");
using宣言では、変数が宣言されたスコープを抜けるタイミングで Dispose が呼ばれます。
さらに、C#には using static、usingエイリアス、global using、暗黙的なusingなどの機能もあります。
初心者がまず押さえるべきポイントは、次の2つです。
usingディレクティブ は、namespaceを読み込んで型名を短く書くためのものです。
usingステートメント と using宣言 は、Disposeが必要なリソースを自動で解放するためのものです。
同じ using というキーワードでも、使われる場所によって役割が変わります。
C# usingとは何かを正しく理解することで、コードを読みやすく書けるだけでなく、ファイルや接続などのリソースも安全に扱えるようになります。

