私は、管理された使い捨てリソース(.NET PerformanceCounter)を所有する基本クラスを持っています。クラスにIDisposableを実装することについて理解しているので、リソースに対してDisposeを明示的に呼び出すことができます。私が見てきた例から、人々は通常、privateのbooleanメンバ変数 "dropped"を使用してDispose内でtrueに設定します。後で、パブリックメソッドまたはプロパティにアクセスしようとすると、 "dropped"がtrueの場合にObjectDisposedExceptionが発生します。管理された使い捨てリソースを所有するIDisposable基本クラス、サブクラスで何をするか?
サブクラスはどうですか?サブクラスは、パブリックメソッドとプロパティで、どのように処分されたかを知っていますか?最初に、サブクラスは削除する必要があるのは基本クラスにしかないので、サブクラスは特別な(Disposeの独自のバージョンを実装するような)必要はないと考えました。(サブクラスは、明示的に処理する必要があります)、基底クラスのDisposeはそれを処理します。サブクラスは、それ自身の "廃棄された"メンバ変数を設定するためだけに、基本クラスの仮想Disposeメソッドをオーバーライドする必要がありますか?
ここでは、問題のクラス階層を非常に簡略化したバージョンです。我々のシステムでは
class BaseCounter : IBaseCounter, IDisposable
{
protected System.Diagnostics.PerformanceCounter pc;
private bool disposed;
public BaseCounter(string name)
{
disposed = false;
pc = CreatePerformanceCounter(name);
}
#region IBaseCounter
public string Name
{
get
{
if (disposed) throw new ObjectDisposedException("object has been disposed");
return pc.CounterName;
}
}
public string InstanceName
{
get
{
if (disposed) throw new ObjectDisposedException("object has been disposed");
return pc.InstanceName;
}
}
#endregion IBaseCounter
#region IDisposable
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
if (pc != null)
{
pc.Dispose();
}
pc = null;
disposed = true;
}
}
}
public void Dispose()
{
Dispose(true);
}
#endregion IDisposable
}
class ReadableCounter : BaseCounter, IReadableCounter //my own interface
{
public ReadableCounter(string name)
: base(name)
{
}
#region IReadableCounter
public Int64 CounterValue()
{
return pc.RawValue;
}
#endregion IReadableCounter
}
class WritableCounter : BaseCounter, IWritableCounter
{
public WritableCounter(string name)
: base(name)
{
}
#region IWritableCounter
public Increment()
{
pc.Increment();
}
#endregion IWritableCounter
}
、ReadableCounterとWritableCounterはBaseCounterのサブクラスだけであり、それらのみコード生成プロセスを介して1つの以上のレベルにサブクラス化されています。追加のサブクラス化レベルは、特定の名前を追加するだけで、名前付きカウンタに直接対応するオブジェクトを作成できるようになります(例えば、生成されたウィジェットの数をカウントするカウンタがある場合、WidgetCounterクラスにカプセル化されます。WidgetCounterには "WidgetCounter"パフォーマンスカウンタを作成するための知識(実際には文字列としてのカウンタ名)が含まれています。
コード生成クラスのみが開発者によって直接使用されるため、この:
だから、class WritableWidgetCounter : WritableCounter
{
public WritableWidgetCounter
: base ("WidgetCounter")
{
}
}
class ReadableWidgetCounter : ReadableCounter
{
public ReadableWidgetCounter
: base ("WidgetCounter")
{
}
}
、あなたはサブクラスを使用しながら、ベースクラスが(使い捨て)PerformanceCounterオブジェクトを所有し、管理していることがわかりパフォーマンスカウンター。
私はこのようなコードがある場合:WritableCounterそれが配置されていたことを、増分では、知っている可能性がどのように
IWritableCounter wc = new WritableWidgetCounter();
wc.Increment();
wc.Dispose();
wc.Increment();
wc = null;
を?単にReadableCounter/WritableCounterレベル "に配置された" メンバ変数を設定する
protected virtual void Dispose(bool disposing)
{
disposed = true; //Nothing to dispose, simply remember being disposed
base.Dispose(disposing); //delegate to base
}
:ReadableCoutnerとWritableCounterは、単にこのようなBaseCounterの
protected virtual void Dispose(bool disposing)
何かをオーバーライドする必要がありますか?
基本クラス(BaseCounter)が宣言されて保護された(または保護されたプロパティになった)場合はどうですか?そうすれば、サブクラスはDisposeが発生したことを覚えておく目的でDisposeメソッドを追加するのではなく、それを参照することができます。
私はこれにボートを紛失していますか?
この回答とAlan McBeeの次の回答は有効だと思います。私の状況では、この答えは私が望む行動に近い(基本クラスは使い捨てで、サブクラスは使い捨てですが、実際には使い捨てリソースはありません)と考えています。私も同様のアプローチを見つけました: http://gregbeech.com/blogs/tech/archive/2007/03/07/implementing-and-using-theididposposable-interface.aspx – wageoghe