IDisposableインターフェースはリソースのクリーンアップの中心となるもので、C#では2つの重要な役割を持っています。
Dispose()メソッドを呼んで)知らせる責任があることを示します。そうすれば、クラスはアンマネージドリソースを解放したり、必要に応じて内部状態をリセットしたりできます。これは、後始末のすべてを(主にメモリの解放を)ガベージコレクターに任せるという通常のやり方とは対照的です。IDisposableインターフェースはresource-lifetime演習で説明するusing文を支えています。Dispose()が、何らかの汎用的なクリーンアップルーチンの中でインターフェースを通して呼ばれることもありえますが、まれです。
IDisposableは、System.IO.StreamやSystem.IO.TextReaderのように、オペレーティングシステムの(アンマネージド)リソースをラップするライブラリクラスで最もよく出会います。(StreamとTextReaderは別の演習で扱います。)
public class TextHandler : IDispoable
{
private TextReader reader = new TextReader(...);
public void Dispose()
{
reader.Dispose();
}
}
使っているクラスがIDispoableインターフェースを実装しているなら、そのインスタンスが不要になったときにDispose()が確実に呼ばれるようにしなければなりません(catchとfinally節を使います)。あるクラスがIDisposableを実装するメンバーを持っているなら、そのクラス自身もIDisposableを実装する必要があるでしょう。そうすれば、IDisposbleを実装するメンバーを破棄するためにDispose()を呼べます。
public class Activity : IDisposable
{
private MyResource myResource;
public Activity()
{
myResource = new MyResource();
}
public void Perform()
{
try
{
myResource.BeUseful();
}
catch (Exception)
{
myResource.Dispose();
}
}
public void Dispose()
{
myResource.Dispose();
}
}
IDisposableインターフェースは、アンマネージドリソースがまったく絡んでいなくても役に立つことがあります。たとえば、長く生きるオブジェクトがあり、そのオブジェクトに短命なオブジェクトたちが自分自身を登録し、不要になったら登録を解除する必要があるとします。短命なオブジェクトのほうでIDisposableを実装すれば、そのクラスを使う開発者に、短命なオブジェクトの寿命の終わりにDispose()を呼ぶ必要があることを知らせられます。
ドキュメントの中に、dispose patternへの言及を見かけるでしょう。_Disposeパターン_には、クラスのファイナライザーからDispose()を呼ぶことや、基底クラスにあるリソースの破棄が正しく処理されるようにすることが含まれます。_Disposeパターン_は後の演習で扱います。
_Disposeパターン_は、主にアンマネージドリソースに関係するものです。P/Invokeの仕組みとexternメソッドを使っているなら、Disposeパターンをいつ、どのように実装すべきかを理解する必要があります。ほとんどのC#開発者は、こうした形でアンマネージドリソースを直接扱うことはほとんどありません。