C# で開発をしていると、ファイルやネットワーク接続、データベース接続など「リソースの解放」が必要な処理に多く出会います。リソースを正しく解放しないと、メモリリークや接続数の枯渇といった問題につながります。そのために用意されている仕組みが IDisposable
インターフェースと using
宣言です。本記事ではその基本とベストプラクティスを解説します。
IDisposableとは?
IDisposable
はリソース解放を行うためのインターフェースで、Dispose()
メソッドを持ちます。このメソッドを実装することで、使用後に明示的にリソースを解放できます。
class SampleResource : IDisposable
{
public void Use()
{
Console.WriteLine("リソースを利用中...");
}
public void Dispose()
{
Console.WriteLine("リソースを解放しました。");
}
}
class Program
{
static void Main()
{
var resource = new SampleResource();
resource.Use();
resource.Dispose(); // 手動で解放
}
}
usingステートメント(従来の書き方)
毎回 Dispose()
を呼ぶのは忘れやすいため、C# では using
ステートメントを使うのが基本です。ブロックを抜けたタイミングで自動的に Dispose()
が呼ばれます。
using (var reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
// ブロックを抜けた時点で自動的に Dispose() が呼ばれる
using宣言(C# 8.0 以降の書き方)
C# 8.0 からは using
宣言が導入され、スコープを明示的にブロックで囲まなくても、自動的にスコープ終了時に解放されます。
using var writer = new StreamWriter("output.txt");
writer.WriteLine("Hello World!");
// このスコープを抜けると自動的に Dispose() が呼ばれる
コードがシンプルになり、ネストが深くなるのを避けられます。
実際の利用例:ファイル読み書き
using var reader = new StreamReader("input.txt");
string content = reader.ReadToEnd();
using var writer = new StreamWriter("output.txt");
writer.WriteLine(content.ToUpper());
このように using
を使うことで、ファイル操作後に確実にファイルハンドルが解放されます。
ベストプラクティス
- リソースを扱うクラスは
IDisposable
を実装する - 利用側では必ず
using
を使ってリソースを解放する - C# 8.0 以降は
using var
宣言 を活用してコードを簡潔に Dispose()
の中では例外を投げないように注意する
まとめ
C# におけるリソース管理の基本は IDisposable
と using
にあります。
Dispose()
を正しく実装し、利用側では using
を徹底することで、リソースリークを防ぎ、安全で安定したアプリケーションを構築できます。