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 を徹底することで、リソースリークを防ぎ、安全で安定したアプリケーションを構築できます。
