我有一个拥有托管一次性资源(.NET PerformanceCounter)的基类。我了解在类上实现 IDisposable 以便我可以在资源上显式调用 Dispose。从我看到的示例中,人们通常使用私有布尔成员变量“disposed”并将其在 Dispose 内部设置为 true。稍后,如果尝试访问公共方法或属性,如果“disposed”为真,则会引发 ObjectDisposedException。
在子类中呢?子类如何在其公共方法和属性中知道它们已被释放?起初我认为子类不需要任何特殊的东西(比如实现他们自己的 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 的唯一子类,它们只是通过代码生成过程再被子类化到一个级别。附加的子类级别只添加了一个特定的名称,以便可以创建直接对应于命名计数器的对象(例如,如果有一个计数器用于计算生成的小部件的数量,它最终被封装在一个 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;
WritableCounter 如何以增量方式知道它已被处置?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 方法。
我错过了这艘船吗?