csharp usingとは?名前空間・リソース解放・using文の使い方を初心者向けに徹底解説

はじめに

C#を学び始めると、かなり早い段階で登場するのがusingです。

たとえば、次のようなコードを見たことがあるかもしれません。

C#
using System;

Console.WriteLine("Hello, World!");

一方で、ファイルを開くコードでは次のようなusingも登場します。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}

さらに、C# 8.0以降では次のような書き方もあります。

C#
using var reader = new StreamReader("sample.txt");

同じusingというキーワードなのに、使われる場所や意味が違うため、初心者にとっては混乱しやすいポイントです。

この記事では、csharp usingをテーマに、C#におけるusingの意味、名前空間の読み込み、リソース解放、using文、using宣言、よくあるエラーまで、初心者向けに順番に解説します。

1. csharp usingとは?初心者がまず押さえる3つの意味

C#のusingには、主に次のような意味があります。

1つ目は、名前空間を読み込むためのusingディレクティブです。

C#
using System;

2つ目は、使い終わったリソースを自動的に解放するためのusing文です。

C#
using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}

3つ目は、C# 8.0以降で使えるusing宣言です。

C#
using var reader = new StreamReader("sample.txt");
Console.WriteLine(reader.ReadToEnd());

この3つはすべてusingというキーワードを使いますが、目的が異なります。

1-1. C#のusingは「名前空間の読み込み」と「リソース解放」に使うキーワード

C#のusingを大きく分けると、役割は2つです。

1つは、クラスやメソッドを短い名前で使えるようにするためのものです。

C#
using System;

Console.WriteLine("Hello");

この場合、Systemという名前空間を読み込んでいるため、Console.WriteLineと短く書けます。

もう1つは、ファイル、ストリーム、データベース接続など、使い終わったあとに明示的な後片付けが必要なものを自動で解放するためのものです。

C#
using (var file = File.OpenRead("sample.txt"))
{
// ファイルを使う処理
}

この場合、usingブロックを抜けると、ファイルが自動的に閉じられます。

1-2. usingディレクティブ・using文・using宣言の違い

C#のusingは、使い方によって名前が異なります。

usingディレクティブは、ファイルの先頭などに書くものです。

C#
using System;
using System.IO;

これは、名前空間を省略して書けるようにするための記述です。

using文は、リソースを扱う処理をブロックで囲む書き方です。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

ブロックを抜けると、自動的にDisposeが呼ばれます。

using宣言は、C# 8.0以降で使える書き方です。

C#
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();

ブロックで囲まなくても、スコープの終了時に自動でDisposeされます。

1-3. なぜ同じusingなのに意味が複数あるのか

C#では、同じキーワードが文脈によって異なる役割を持つことがあります。

usingもその1つです。

ファイルの先頭に書かれている場合は、名前空間を読み込む意味になります。

C#
using System;

一方、メソッドの中で次のように書かれている場合は、リソースを自動解放する意味になります。

C#
using (var stream = new FileStream("sample.txt", FileMode.Open))
{
// 処理
}

さらに、C# 8.0以降ではメソッド内で次のように書くこともできます。

C#
using var stream = new FileStream("sample.txt", FileMode.Open);

つまり、usingそのものの意味を丸暗記するのではなく、「どこに書かれているか」「どの形で書かれているか」を見て判断することが重要です。

1-4. この記事で解説するusingの全体像

この記事では、C#のusingを次の順番で解説します。

まず、using System;のような名前空間を扱うusingディレクティブを説明します。

次に、ファイルやデータベース接続などを安全に扱うためのusing文を解説します。

そのあと、C# 8.0以降で使えるusing宣言を紹介します。

さらに、実践的なコード例、よくあるエラー、ベストプラクティス、importnamespaceとの違い、global usingなどの関連知識も扱います。

2. 名前空間を扱うusingディレクティブの使い方

C#で最もよく見るusingの1つが、名前空間を読み込むusingディレクティブです。

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

これは、コード内でクラス名を短く書けるようにするために使います。

2-1. using System; の意味を初心者向けに解説

using System;は、System名前空間に含まれるクラスや型を使いやすくするための記述です。

たとえば、ConsoleクラスはSystem名前空間に属しています。

using System;を書いていれば、次のように書けます。

C#
using System;

Console.WriteLine("こんにちは");

もしusing System;を書かない場合は、次のように完全な名前で書く必要があります。

C#
System.Console.WriteLine("こんにちは");

どちらも同じ意味ですが、using System;を書いたほうがコードが短くなり、読みやすくなります。

2-2. 名前空間とは何か

名前空間とは、クラスや型を整理するための入れ物のようなものです。

C#には多くのクラスがあります。たとえば、文字を画面に出力するConsole、ファイルを扱うFile、リストを扱うList<T>などがあります。

これらをすべて同じ場所に置いてしまうと、名前の衝突が起こりやすくなります。

そこで、C#では名前空間を使ってクラスを分類します。

C#
System.Console
System.IO.File
System.Collections.Generic.List<T>

SystemSystem.IOSystem.Collections.Genericが名前空間です。

2-3. usingを書かない場合のコード例

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("Alice");
names.Add("Bob");

foreach (string name in names)
{
System.Console.WriteLine(name);
}
}
}

このように、毎回System.ConsoleSystem.Collections.Generic.List<string>と書くと、コードが長くなります。

特に、複数のクラスを使うプログラムでは読みにくくなります。

2-4. usingを書くとコードが短くなる理由

usingを書くと、名前空間の部分を省略できます。

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

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

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

names.Add("Alice");
names.Add("Bob");

foreach (string name in names)
{
Console.WriteLine(name);
}
}
}

System.ConsoleConsoleSystem.Collections.Generic.List<string>List<string>と書けるようになりました。

このように、usingディレクティブはコードを短くし、読みやすくするために使います。

2-5. よく使う名前空間の例

C#でよく使われる名前空間には、次のようなものがあります。

C#
using System;

ConsoleDateTimeMathなど、基本的なクラスを使うときによく使います。

C#
using System.Collections.Generic;

List<T>Dictionary<TKey, TValue>など、コレクションを使うときに使います。

C#
using System.IO;

FileStreamReaderFileStreamなど、ファイル操作をするときに使います。

C#
using System.Linq;

配列やリストを便利に操作するLINQを使うときに使います。

C#
using System.Threading.Tasks;

非同期処理でTaskを使うときに使います。

2-6. usingディレクティブを書く場所

usingディレクティブは、通常、C#ファイルの先頭に書きます。

C#
using System;
using System.IO;

namespace SampleApp
{
class Program
{
static void Main()
{
Console.WriteLine("Hello");
}
}
}

また、名前空間の内側に書くこともできます。

C#
namespace SampleApp
{
using System;

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

ただし、初心者のうちはファイルの先頭にまとめて書く形を覚えるとよいでしょう。

C# 10以降では、global usingや暗黙的なusingが使われることもあります。そのため、最近のプロジェクトではusing System;が見当たらないのにConsole.WriteLineが使える場合もあります。

2-7. 不要なusingは削除してもよいのか

不要なusingは削除して問題ありません。

たとえば、System.IOを使っていないのに次のように書いている場合です。

C#
using System;
using System.IO;

Console.WriteLine("Hello");

このコードではSystem.IOを使っていないため、削除できます。

C#
using System;

Console.WriteLine("Hello");

不要なusingを残してもプログラムがすぐに壊れるわけではありませんが、コードが整理されていたほうが読みやすくなります。

Visual Studioでは、不要なusingを自動で削除したり並べ替えたりできます。

3. using文とは?リソースを自動で解放する仕組み

C#のusingには、リソースを自動で解放するためのusing文があります。

ファイル、ストリーム、データベース接続などは、使い終わったあとに閉じる必要があります。

using文を使うと、処理が終わったタイミングで自動的に後片付けが行われます。

3-1. using文の基本構文

using文の基本構文は次のとおりです。

C#
using (リソースを作成する式)
{
// リソースを使う処理
}

具体例は次のようになります。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}

このコードでは、StreamReaderを使ってファイルを読み込んでいます。

usingブロックを抜けると、reader.Dispose()が自動的に呼ばれ、ファイルが閉じられます。

3-2. ファイル・データベース接続・ストリームでusingが必要な理由

ファイルやデータベース接続などは、メモリだけでなくOSや外部システムのリソースを使います。

たとえば、ファイルを開いたままにすると、ほかの処理がそのファイルを編集できなくなる場合があります。

データベース接続を閉じないまま放置すると、接続数が増え続け、最終的に新しい接続ができなくなることがあります。

ストリームを閉じないと、データが正しく書き込まれなかったり、リソースリークの原因になったりします。

そのため、使い終わったリソースは確実に解放する必要があります。

C#
using (var stream = new FileStream("sample.txt", FileMode.Open))
{
// ファイルを読む処理
}

using文を使えば、例外が発生した場合でもリソースが解放されます。

3-3. Disposeとは何か

Disposeとは、使い終わったリソースを解放するためのメソッドです。

たとえば、次のような処理をイメージするとわかりやすいです。

C#
var reader = new StreamReader("sample.txt");

// ファイルを読む処理

reader.Dispose();

Disposeを呼ぶことで、内部で使っていたファイルやストリームなどのリソースを解放します。

ただし、手動でDisposeを書くと、途中で例外が発生したときに呼び忘れる可能性があります。

そこでusing文を使います。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

この書き方なら、ブロックを抜けるときに自動的にDisposeが呼ばれます。

3-4. IDisposableインターフェースとの関係

using文で扱えるオブジェクトは、基本的にIDisposableインターフェースを実装している必要があります。

IDisposableは、次のようなインターフェースです。

C#
public interface IDisposable
{
void Dispose();
}

つまり、Disposeメソッドを持っている型です。

たとえば、StreamReaderFileStreamSqlConnectionなどはIDisposableを実装しています。

そのため、using文で安全に扱うことができます。

C#
using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}

一方、IDisposableを実装していない通常のクラスに対してusing文を使うことはできません。

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);
}
}
}

このコードでは、sample.txtを開いて中身を読み込み、画面に表示しています。

usingブロックの中ではreaderを使えますが、ブロックを抜けるとreaderは破棄されます。

そのため、次のようにブロックの外で使うことはできません。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

// ここではreaderは使えない

3-6. using文を使わないと起きる問題

using文を使わずにリソースを閉じ忘れると、さまざまな問題が起きる可能性があります。

たとえば、次のコードはよくありません。

C#
var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);

このコードでは、readerを閉じていません。

正しくは、最後にDisposeを呼ぶ必要があります。

C#
var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
reader.Dispose();

しかし、この書き方では、途中で例外が発生した場合にDisposeが呼ばれない可能性があります。

C#
var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();

// ここで例外が発生するとDisposeされない可能性がある
Console.WriteLine(text);

reader.Dispose();

そのため、リソースを扱う場合はusing文を使うのが安全です。

3-7. 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();
}
}

finallyは、例外が発生しても実行される場所です。

つまり、using文を使うと、例外が発生してもリソースを確実に解放できます。

4. using宣言とは?C# 8.0以降の新しい書き方

C# 8.0以降では、using宣言という書き方が使えるようになりました。

using宣言は、using文よりもシンプルに書けるリソース解放の構文です。

4-1. using宣言の基本構文

using宣言の基本構文は次のとおりです。

C#
using var 変数名 = new リソース型();

具体例を見てみましょう。

C#
using var reader = new StreamReader("sample.txt");

string text = reader.ReadToEnd();
Console.WriteLine(text);

using文のように波かっこでブロックを作る必要がありません。

ただし、readerはスコープの終了時に自動的にDisposeされます。

4-2. using文との違い

using文は、ブロックを抜けたタイミングでDisposeされます。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}

// ここではすでにDisposeされている

一方、using宣言は、宣言されたスコープの終了時にDisposeされます。

C#
void ReadFile()
{
using var reader = new StreamReader("sample.txt");

string text = reader.ReadToEnd();
Console.WriteLine(text);

// メソッドの終わりでDisposeされる
}

つまり、using宣言はコードを短くできますが、どこでDisposeされるのかをスコープから判断する必要があります。

4-3. スコープ終了時にDisposeされる仕組み

using宣言では、変数が宣言されたスコープの終了時にDisposeが呼ばれます。

たとえば、次のコードでは、readerReadFileメソッドの終了時に破棄されます。

C#
void ReadFile()
{
using var reader = new StreamReader("sample.txt");

string text = reader.ReadToEnd();
Console.WriteLine(text);
}

一方、ブロックの中で宣言した場合は、そのブロックの終了時に破棄されます。

C#
void ReadFile()
{
{
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
}

// ここではreaderはDispose済み
}

using宣言を使うときは、どの範囲までリソースを保持するのかを意識することが大切です。

4-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文はブロック終了時、using宣言はスコープ終了時にDisposeされる点です。

4-5. 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);

ネストが減り、処理の流れを追いやすくなります。

4-6. 初心者はusing文とusing宣言のどちらを使うべきか

初心者は、まずusing文から覚えるのがおすすめです。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

理由は、リソースが使える範囲と破棄されるタイミングが波かっこで明確に見えるからです。

慣れてきたら、using宣言も使うとよいでしょう。

C#
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();

ただし、using宣言はスコープの終了時までリソースが保持されます。短い処理では便利ですが、長いメソッドで多用すると、いつ解放されるのかがわかりにくくなる場合があります。

5. usingの実践例で理解する使い方

ここからは、実際のコードを使ってusingの使い方を確認します。

csharp usingを理解するには、名前空間の読み込みとリソース解放の両方をコードで見ることが大切です。

5-1. Console.WriteLineでusing Systemを使う例

まずは、using System;の例です。

C#
using System;

class Program
{
static void Main()
{
Console.WriteLine("Hello, C#");
}
}

ConsoleクラスはSystem名前空間に含まれています。

そのため、using System;を書くことで、System.Console.WriteLineではなくConsole.WriteLineと書けます。

using System;を書かない場合は、次のようになります。

C#
class Program
{
static void Main()
{
System.Console.WriteLine("Hello, C#");
}
}

どちらも動作は同じですが、using System;を書いたほうが簡潔です。

5-2. ファイル読み込みで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);
}
}
}

このコードでは、StreamReaderを使ってsample.txtの内容を読み込んでいます。

usingブロックを抜けると、readerが自動的に破棄されます。

ファイルを扱う処理では、読み込みが終わったあとにファイルを閉じる必要があります。using文を使うことで、その処理を安全に自動化できます。

5-3. StreamReaderとusingの組み合わせ

StreamReaderは、テキストファイルを読み込むときによく使うクラスです。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
using (StreamReader reader = new StreamReader("data.txt"))
{
string? line;

while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
}

この例では、ファイルを1行ずつ読み込んでいます。

StreamReaderIDisposableを実装しているため、using文で扱えます。

処理が終わると自動的にDisposeされ、ファイルが閉じられます。

5-4. データベース接続でusingを使う例

データベース接続でもusingはよく使われます。

たとえば、SQL Serverに接続する場合は次のように書きます。

C#
using Microsoft.Data.SqlClient;

string connectionString = "接続文字列をここに書く";

using (var connection = new SqlConnection(connectionString))
{
connection.Open();

using (var command = new SqlCommand("SELECT Name FROM Users", connection))
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine(reader["Name"]);
}
}
}

データベース接続は、使い終わったら確実に閉じる必要があります。

SqlConnectionSqlCommandSqlDataReaderのようなクラスはリソースを持つため、usingで管理することが多いです。

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);
}

この書き方では、readerstreamの両方が自動的にDisposeされます。

using宣言を使う場合は、次のように書けます。

C#
using var stream = new FileStream("sample.txt", FileMode.Open);
using var reader = new StreamReader(stream);

string text = reader.ReadToEnd();
Console.WriteLine(text);

どちらの書き方でも、複数のリソースを安全に扱えます。

5-6. await usingを使う非同期リソース解放の基本

C#には、非同期でリソースを解放するためのawait usingもあります。

await usingは、IAsyncDisposableを実装した型に対して使います。

C#
await using var resource = new AsyncResource();

await resource.DoSomethingAsync();

イメージとしては、通常のusingDisposeを呼ぶのに対して、await usingDisposeAsyncを呼びます。

簡単な例は次のとおりです。

C#
public class AsyncResource : IAsyncDisposable
{
public async ValueTask DisposeAsync()
{
await Task.Delay(100);
Console.WriteLine("非同期でリソースを解放しました");
}

public async Task DoSomethingAsync()
{
await Task.Delay(100);
Console.WriteLine("処理を実行しました");
}
}

使う側は次のようになります。

C#
await using var resource = new AsyncResource();

await resource.DoSomethingAsync();

非同期処理でリソース解放にも時間がかかる場合は、await usingを使います。

6. usingでよくあるエラーと対処法

C#のusingでは、初心者がつまずきやすいエラーがいくつかあります。

ここでは、代表的なエラーと対処法を紹介します。

6-1. 型または名前空間の名前が見つからない

よくあるエラーの1つが、次のようなメッセージです。

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

この場合、必要な名前空間のusingが不足している可能性があります。

StreamReaderを使うには、通常、次のusingが必要です。

C#
using System.IO;

修正例は次のとおりです。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
using (var reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}

6-2. usingを追加してもエラーが消えない原因

usingを追加してもエラーが消えない場合があります。

その原因として多いのは、そもそも必要なライブラリがプロジェクトに追加されていないケースです。

usingは、すでに参照できるライブラリ内の名前空間を省略して書けるようにするだけです。

つまり、usingを書けば自動的にライブラリがインストールされるわけではありません。

たとえば、外部パッケージのクラスを使う場合は、NuGetパッケージを追加する必要があります。

6-3. 参照設定やNuGetパッケージが不足しているケース

たとえば、SQL Server用のSqlConnectionを使いたい場合、次のようなusingを書くことがあります。

C#
using Microsoft.Data.SqlClient;

しかし、プロジェクトにMicrosoft.Data.SqlClientパッケージが追加されていなければ、エラーになります。

この場合は、NuGetからパッケージを追加します。

Visual Studioでは、プロジェクトを右クリックして「NuGet パッケージの管理」から追加できます。

コマンドラインでは、次のように追加できます。

Bash
dotnet add package Microsoft.Data.SqlClient

そのうえで、コードにusingを書きます。

C#
using Microsoft.Data.SqlClient;

usingと参照設定は別物だと理解しておきましょう。

6-4. Disposeが存在しない型にusing文を使った場合

using文using宣言は、基本的にIDisposableまたはIAsyncDisposableを実装した型に使います。

たとえば、次のようなクラスがあるとします。

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

このクラスに対して次のように書くと、エラーになります。

C#
using (var user = new User())
{
Console.WriteLine(user.Name);
}

UserクラスはIDisposableを実装していないため、usingで扱えません。

using文は、何でも囲める便利構文ではなく、リソース解放が必要な型に使うものです。

6-5. usingのスコープを勘違いした場合の注意点

using文で宣言した変数は、ブロックの中でしか使えません。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

Console.WriteLine(reader.ReadToEnd()); // エラー

readerusingブロックの外では使えません。

また、using宣言では、スコープの終了時にDisposeされます。

C#
void ReadFile()
{
using var reader = new StreamReader("sample.txt");

string text = reader.ReadToEnd();
Console.WriteLine(text);
} // ここでDisposeされる

using宣言は便利ですが、長いメソッドで使うと、思ったより長くリソースを保持してしまうことがあります。

6-6. Visual Studioでusingを自動追加・整理する方法

Visual Studioでは、必要なusingを自動追加できます。

たとえば、List<string>を書いたときにusing System.Collections.Generic;が不足していると、候補が表示されます。

クイックアクションからusingを追加できます。

また、不要なusingを削除したり、並び替えたりすることもできます。

コードを右クリックして「using の整理」を実行すると、不要なusingを削除できます。

これにより、コードをきれいに保つことができます。

7. usingを使うときの注意点とベストプラクティス

usingは便利ですが、正しく使わないとコードが読みにくくなったり、意図しないタイミングでリソースが解放されたりします。

ここでは、C#でusingを使うときの注意点を解説します。

7-1. 不要なusingは残さない

使っていないusingディレクティブは削除しましょう。

C#
using System;
using System.IO;
using System.Text;

このうち、System.Textを使っていないなら削除して問題ありません。

不要なusingが多いと、そのファイルで何を使っているのかがわかりにくくなります。

Visual StudioやVisual Studio Codeの機能を使えば、自動で整理できます。

7-2. リソースを扱うクラスではusingを検討する

ファイル、ストリーム、データベース接続、ネットワーク接続などを扱う場合は、usingを使うべきか確認しましょう。

たとえば、次のような型はusingで扱うことが多いです。

C#
StreamReader
FileStream
MemoryStream
SqlConnection
SqlCommand
HttpResponseMessage

これらは、使い終わったあとにリソース解放が必要になる場合があります。

IDisposableを実装している型を使うときは、usingを検討する習慣をつけるとよいでしょう。

7-3. Dispose後のオブジェクトを使わない

Disposeされたオブジェクトは、基本的に使ってはいけません。

C#
StreamReader reader;

using (reader = new StreamReader("sample.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}

// Dispose後なので使わない
Console.WriteLine(reader.ReadToEnd());

このようなコードを書くと、実行時エラーになる可能性があります。

usingブロックを抜けたあと、またはusing宣言のスコープが終了したあと、そのオブジェクトは使わないようにしましょう。

7-4. スコープを意識してusing文を書く

usingでは、スコープを意識することが重要です。

短い範囲だけリソースを使うなら、using文がわかりやすいです。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}

この書き方なら、readerがどこまで使えるか明確です。

一方、using宣言を使う場合は、スコープの終わりまでリソースが保持されます。

C#
using var reader = new StreamReader("sample.txt");

// このスコープの終わりまでreaderが保持される

長いメソッドでは、リソースを早めに解放するためにusing文を使ったほうが読みやすい場合があります。

7-5. using varを多用しすぎない

using varは便利ですが、多用しすぎるとリソースの解放タイミングが見えにくくなる場合があります。

C#
using var stream = new FileStream("sample.txt", FileMode.Open);
using var reader = new StreamReader(stream);

// たくさんの処理

// メソッドの最後でDispose

短いメソッドでは問題ありませんが、長いメソッドではreaderstreamがいつまで生きているのかがわかりにくくなります。

明確にリソースの使用範囲を示したい場合は、従来のusing文を使うとよいでしょう。

7-6. コードの読みやすさを優先する

using文using宣言のどちらが常に正しいというわけではありません。

大切なのは、コードを読む人が理解しやすいことです。

リソースの使用範囲をはっきり見せたいなら、using文が向いています。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

短くシンプルな処理なら、using宣言が向いています。

C#
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();

チーム開発では、プロジェクトのコーディングルールに合わせることも大切です。

8. usingと似た概念・混同しやすい用語

C#のusingは、ほかの言語のimportや、C#のnamespace、参照設定などと混同されやすいです。

ここでは、似ている用語との違いを整理します。

8-1. usingとimportの違い

JavaやPythonでは、外部の機能を使うときにimportを使います。

C#では、それに近い役割を持つのがusingディレクティブです。

C#の例です。

C#
using System;
using System.IO;

Javaの例です。

Java
import java.util.List;

Pythonの例です。

Python
import os

ただし、C#のusingは単なるimportだけではありません。

リソース解放のためのusing文using宣言もあります。

そのため、C#のusingは文脈によって意味を判断する必要があります。

8-2. usingとnamespaceの違い

namespaceは、クラスを分類するための仕組みです。

C#
namespace MyApp.Services
{
public class UserService
{
}
}

一方、usingは、その名前空間に含まれる型を短く書けるようにするものです。

C#
using MyApp.Services;

var service = new UserService();

namespaceは「所属先を定義するもの」、usingは「別の名前空間を使いやすくするもの」と考えるとわかりやすいです。

8-3. usingと参照設定の違い

usingと参照設定は別物です。

usingは、名前空間を省略して書けるようにする記述です。

C#
using Microsoft.Data.SqlClient;

一方、参照設定やNuGetパッケージの追加は、プロジェクトからそのライブラリを使えるようにする作業です。

つまり、ライブラリ自体がプロジェクトに追加されていなければ、usingを書いても使えません。

順番としては、まず参照設定やNuGetパッケージを追加し、そのあと必要に応じてusingを書くと考えるとよいでしょう。

8-4. usingとstatic usingの違い

C#には、using staticという書き方もあります。

C#
using static System.Math;

class Program
{
static void Main()
{
double result = Sqrt(16);
Console.WriteLine(result);
}
}

通常は、Math.Sqrt(16)と書きます。

C#
double result = Math.Sqrt(16);

しかし、using static System.Math;を書くと、Math.を省略してSqrt(16)と書けます。

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

初心者のうちは、通常のusingを中心に覚えるとよいでしょう。

8-5. usingエイリアスの使い方

usingには、別名を付ける使い方もあります。

これをusingエイリアスと呼びます。

C#
using IO = System.IO;

class Program
{
static void Main()
{
string text = IO.File.ReadAllText("sample.txt");
Console.WriteLine(text);
}
}

この例では、System.IOIOという別名を付けています。

また、同じ名前のクラスが複数の名前空間に存在する場合にも便利です。

C#
using ProjectTask = MyApp.Models.Task;
using ThreadTask = System.Threading.Tasks.Task;

このようにエイリアスを使うと、名前の衝突を避けることができます。

8-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プロジェクトでは、よく使う名前空間が暗黙的に読み込まれる設定になっている場合があります。

そのため、using System;を書いていないのにConsole.WriteLineが使えることがあります。

ただし、初心者のうちは、まず通常のusingを理解してからglobal usingを学ぶとよいでしょう。

9. csharp usingに関するよくある質問

ここでは、csharp usingに関して初心者が疑問に思いやすい点をQ&A形式で解説します。

9-1. using System; は必ず必要ですか?

必ず必要とは限りません。

using System;を書かなくても、次のように完全修飾名で書けば動きます。

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

また、C# 10以降のプロジェクトでは、暗黙的なusingによってSystemが自動的に使える場合もあります。

ただし、基本を学ぶ段階では、using System;を書くとConsole.WriteLineを短く書けると理解しておけば十分です。

9-2. usingを書けばライブラリを使えるようになりますか?

usingを書くだけでは、ライブラリが使えるようになるとは限りません。

usingは、すでに参照できる名前空間を短く書けるようにするものです。

外部ライブラリを使う場合は、先にNuGetパッケージや参照設定を追加する必要があります。

たとえば、次のusingを書くだけでは不十分な場合があります。

C#
using Microsoft.Data.SqlClient;

プロジェクトにMicrosoft.Data.SqlClientパッケージが入っていなければ、エラーになります。

9-3. using文はいつ使うべきですか?

using文は、使い終わったあとにリソース解放が必要なオブジェクトを扱うときに使います。

代表例は、ファイル、ストリーム、データベース接続などです。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

目安として、使う型がIDisposableを実装している場合は、usingを使うべきか確認するとよいでしょう。

9-4. using文とusing宣言はどちらが新しいですか?

新しいのはusing宣言です。

using文は以前からある書き方です。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

using宣言はC# 8.0以降で使える書き方です。

C#
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();

どちらもリソースを自動解放する目的で使います。

9-5. Disposeは自動で呼ばれますか?

using文using宣言を使った場合は、自動でDisposeが呼ばれます。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

この場合、usingブロックを抜けるとreader.Dispose()が自動的に呼ばれます。

ただし、usingを使っていない場合は、自動でDisposeされるとは限りません。

リソース解放が必要な型を使う場合は、usingを使うのが安全です。

9-6. global usingは初心者も使うべきですか?

初心者が最初からglobal usingを積極的に使う必要はありません。

まずは通常のusingを理解することが大切です。

C#
using System;
using System.IO;

そのうえで、複数のファイルで同じusingを何度も書いている場合や、プロジェクト全体で共通の名前空間を使いたい場合にglobal usingを検討するとよいでしょう。

C#
global using System;
global using System.IO;

global usingは便利ですが、どの名前空間がどこで読み込まれているのかが見えにくくなることもあります。

まとめ

C#のusingには、主に3つの意味があります。

1つ目は、名前空間を読み込むusingディレクティブです。

C#
using System;

これは、System.Console.WriteLineConsole.WriteLineのように短く書くために使います。

2つ目は、リソースを自動で解放するusing文です。

C#
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
}

ファイル、ストリーム、データベース接続など、使い終わったあとに解放が必要なオブジェクトを安全に扱えます。

3つ目は、C# 8.0以降で使えるusing宣言です。

C#
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();

ブロックを書かずに、スコープ終了時に自動でDisposeできます。

初心者は、まずusing System;のような名前空間の読み込みと、using文によるリソース解放を理解することが大切です。

その後、using宣言await usingusing staticusingエイリアスglobal usingを順番に学ぶと、C#のコードをより読みやすく安全に書けるようになります。