これらの単純なクラスから始めます...
次のような単純なクラスのセットがあるとします。
class Bus
{
Driver busDriver = new Driver();
}
class Driver
{
Shoe[] shoes = { new Shoe(), new Shoe() };
}
class Shoe
{
Shoelace lace = new Shoelace();
}
class Shoelace
{
bool tied = false;
}
AにBus
はがありDriver
、にDriver
は2つShoe
のがあり、それぞれにShoe
がありShoelace
ます。すべて非常にばかげています。
IDisposableオブジェクトをShoelaceに追加する
後で、上のいくつかの操作をShoelace
マルチスレッド化できると判断したのでEventWaitHandle
、スレッドが通信するためのを追加します。したがってShoelace
、次のようになります。
class Shoelace
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
// ... other stuff ..
}
IDisposableをShoelaceに実装する
しかし、今度はMicrosoftのFxCopが文句を言うだろう:「IDisposableを次のIDisposable型のメンバーを作成するため、「Shoelace」にIDisposableを実装する:「EventWaitHandle」。
さて、私は実装IDisposable
しShoelace
、私のきちんとした小さなクラスはこの恐ろしい混乱になります:
class Shoelace : IDisposable
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Shoelace()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (waitHandle != null)
{
waitHandle.Close();
waitHandle = null;
}
}
// No unmanaged resources to release otherwise they'd go here.
}
disposed = true;
}
}
または(コメント投稿者が指摘したように)それShoelace
自体にはアンマネージリソースがないため、Dispose(bool)
およびDestructor を必要とせずに、より簡単な破棄の実装を使用できます。
class Shoelace : IDisposable
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
public void Dispose()
{
if (waitHandle != null)
{
waitHandle.Close();
waitHandle = null;
}
GC.SuppressFinalize(this);
}
}
IDisposableが広がっていくのを恐怖で見る
正解です。しかし、FxCopはをShoe
作成すると文句を言うShoelace
ので、そうでShoe
なければなりIDisposable
ません。
そしてDriver
作成Shoe
するDriver
必要がありますIDisposable
。そしてBus
、Driver
そうでBus
なければなりませんIDisposable
。
突然、私の小さな変更によってShoelace
多くの作業が発生し、上司はなぜにBus
変更するためにチェックアウトする必要があるのか疑問に思っていShoelace
ます。
質問
どのようにしてこのの拡散を防ぎIDisposable
ながら、管理されていないオブジェクトが適切に破棄されるようにしますか?