これらの簡単なクラスから始めてください...
次のような単純なクラスのセットがあるとしましょう。
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;
}
ABus
には、がありDriver
、にDriver
は2つShoe
のsがあり、それぞれShoe
に。がありShoelace
ます。すべて非常にばかげています。
IDisposableオブジェクトをShoelaceに追加します
後で、の一部の操作をShoelace
マルチスレッド化できると判断したのでEventWaitHandle
、スレッドが通信するためのを追加します。だからShoelace
今は次のようになります:
class Shoelace
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
// ... other stuff ..
}
靴紐にIDisposableを実装する
しかし、MicrosoftのFxCopは、「次の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実装を使用できます。Dispose(bool)
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
が、それでも管理されていないオブジェクトが適切に廃棄されるようにしますか?