【C#】using宣言とIDisposableの基本|リソース管理のベストプラクティス

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# におけるリソース管理の基本は IDisposableusing にあります。
Dispose() を正しく実装し、利用側では using を徹底することで、リソースリークを防ぎ、安全で安定したアプリケーションを構築できます。