虽然在互联网和SOF上广泛讨论了Dispose Pattern,但我找不到任何可以回答我问题的资源。
因此,在将此标记为副本之前,请善意阅读。如果你能指出我之前错过的一个问题,我会很高兴地删除这个问题。
我见过很多类(盲目地?)实现了dispose模式而没有实现终结器。
MSDN article on Dispose Pattern说:
布尔参数disposing指示是从IDisposable.Dispose实现还是从终结器调用方法。 Dispose(bool)实现应该在访问其他引用对象(例如,前面示例中的资源字段)之前检查参数。只有在从IDisposable.Dispose实现调用方法时才会访问此类对象(当disposing参数等于true时)。 如果从终结器调用该方法(disposing为false),则不应访问其他对象。原因是对象以不可预测的顺序最终确定,因此它们或它们的任何依赖项可能已经完成。
根据我的理解,GC调用终结器方法(如果实现),而后者又调用Dispose(bool)方法,参数为false。
我的第一个问题是,如果一个类没有实现终结器,那么Dispose(bool)是否会被参数调用为false? (例如我在CLR中发现的某些内容我没有遇到过)
我理解Dispose(bool)可以用来确保对象只被处置一次。
因此,我的第二个问题是,如果某个类不需要实现终结器,那么它是否可以简单地实现如下的Dispose方法?
private bool objectDisposed;
public void Dispose()
{
if (!objectDisposed)
{
// Release/dispose managed resources
// ...
// ...
objectDisposed = true;
}
}
答案 0 :(得分:2)
我的第一个问题是,如果一个类没有实现终结器 Dispose(bool)是否被调用参数为false? (例如。 通过我没有遇到过的CLR中的某些内容)
NO
因此,我的第二个问题是一个班级是否需要实施 一个终结器,然后它可以简单地实现像Dispose方法 下面?
我不会,但你可以。如果你这样做,你将重新发明IDisposable模式,如果这个类将被扩展。正如HansPassant在评论中指出的那样,如果有派生类,IDisposable模式会非常方便。我宁愿在第一时间遵循这个模式。
基础课程
using System;
class BaseClass : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
// Only if there are unmanaged resources.
~BaseClass()
{
Dispose(false);
}
}
派生类
using System;
class DerivedClass : BaseClass
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
// Call the base class implementation.
base.Dispose(disposing);
}
// Only if there are unmanaged resources.
~DerivedClass()
{
Dispose(false);
}
}