这将成为IDisposable的有效基类吗?
一次性实施模式非常昂贵。 在开始实际处理资源之前,我已经计算了17行代码。
Eric Lippert最近撰写了一篇博文,提出了一个有趣的观点:任何时候终结者运行,这都是一个错误。 我认为这很有道理。 如果始终遵循IDisposable模式,则始终应终止Finalizer。 它永远不会有机会运行。 如果我们接受finalizer run是一个bug,那么有一个指导原则强制开发人员从以下抽象类派生并禁止直接实现IDisposable接口。
public abstract class AbstractDisaposableBase: IDisposable
{
~AbstractDisaposableBase()
{
ReportObjectLeak();
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected abstract void Dispose(bool disposing);
[Conditional("DEBUG")]
private void ReportObjectLeak()
{
//Debug.Assert(false, "leaked instance");
//throw new Exception("leaked instance");
}
}
好处很明显:
class MyClass1 : DisablableBase
{
protected override void Dispose(bool disposing)
{
//dispose both managed and unmamaged resources as though disposing==true
}
}
未处理的对象被报告
始终遵循一次性格局
但是,这样的指导方针有什么问题吗?
一个可能的问题是所有的一次性物体都会有一个终结器。 但由于终结者总是被压制,所以不应该有任何表现的惩罚。
你怎么看?
有一个指导原则强制开发人员从以下抽象类派生出来是否有意义
不,仅仅是因为C#没有多重继承。 接口描述行为,继承规定“is-a”。 如果您执行此规则,您将彻底限制类的面向对象设计。
例如,您不能为业务对象引入基类,这些业务对象不是一次性的,派生类就是这样。
但由于终结者总是被压制,所以不应该有任何表现的惩罚。
AbstractDisaposableBase
子类的实例仍将参与最终化队列管理,因此会对性能产生影响。