我有一个拥有托管可释放资源(.NET PerformanceCounter)的基类。我了解如何在类上实现IDisposable,以便可以显式调用资源上的Dispose。从我看到的示例中,人们通常使用私有布尔成员变量“disposed”,并在dispose内将其设置为true。稍后,如果试图访问公共方法或属性,则如果“Disposed”为true,则会引发ObjectDisposedException。
在子类中呢?在它们的公共方法和属性中,子类如何知道它们已被释放?首先,我认为子类不需要任何特殊的东西(比如实现它们自己的Dispose版本),因为需要释放的东西只在基类中(假设子类不会添加任何需要显式释放的数据),而基类的Dispose应该处理它。子类是否应仅为了设置自己的“disposed”成员变量而重写基类的“virtual 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的唯一子类,它们通过代码生成过程只被子类化到一个级别。附加的子类化级别只添加一个特定的名称,这样就可以创建与命名计数器直接对应的对象(例如,如果有一个计数器用于计算生成的小部件的数量,那么它最终会被封装到一个widgetCounter类中。widgetcounter包含允许创建“widgetcounter”性能计数器的知识(实际上,只是计数器名称作为字符串)。
只有代码生成的类被开发人员直接使用,所以我们将有如下内容:
class WritableWidgetCounter : WritableCounter
{
public WritableWidgetCounter
: base ("WidgetCounter")
{
}
}
class ReadableWidgetCounter : ReadableCounter
{
public ReadableWidgetCounter
: base ("WidgetCounter")
{
}
}
因此,可以看到基类拥有和管理PerformanceCounter对象(它是可释放的),而子类使用PerformanceCounter。
如果我有这样的代码:
IWritableCounter wc = new WritableWidgetCounter();
wc.Increment();
wc.Dispose();
wc.Increment();
wc = null;
可写计数器如何逐渐知道它已被处理?readablecoutner和writablecounter应该简单地重写basecounter的
protected virtual void Dispose(bool disposing)
像这样:
protected virtual void Dispose(bool disposing)
{
disposed = true; //Nothing to dispose, simply remember being disposed
base.Dispose(disposing); //delegate to base
}
只需设置readablecounter/writablecounter级别的“disposed”成员变量?
如果基类(basecounter)声明为已被释放为受保护的(或使其成为受保护的属性),该如何处理?这样,子类就可以引用它,而不是仅仅为了记住已经发生了Dispose而添加Dispose方法。
我错过了这条船吗?