如果未实现终结器,是否需要 Dispose(bool) 方法?
Is Dispose(bool) method necessary if a finalizer isn't implemented?
虽然 Dispose Pattern 在 Internet 和 SOF 上得到广泛讨论,但我找不到任何资源来回答我的问题。
因此,在将其标记为重复之前,请阅读到最后。如果您能指出我之前遗漏的问题,我会很乐意删除该问题。
我见过很多 class(盲目地?)在没有实现终结器的情况下实现处置模式。
MSDN article on Dispose Pattern 说:
The Boolean parameter disposing indicates whether the method was invoked from the IDisposable.Dispose implementation or from the finalizer. The Dispose(bool) implementation should check the parameter before accessing other reference objects (e.g., the resource field in the preceding sample). Such objects should only be accessed when the method is called from the IDisposable.Dispose implementation (when the disposing parameter is equal to true). If the method is invoked from the finalizer (disposing is false), other objects should not be accessed. The reason is that objects are finalized in an unpredictable order and so they, or any of their dependencies, might already have been finalized.
根据我的理解,GC 调用终结器方法(如果已实现),该方法又应调用参数为 false 的 Dispose(bool) 方法。
我的第一个问题是,如果 class 没有实现终结器,那么 Dispose(bool) 是否曾经被调用时参数为 false? (例如,在 CLR 中我没有遇到过)
我了解 Dispose(bool) 可用于确保对象仅被处理一次。
因此,我的第二个问题是,如果 class 不需要实现终结器,那么它是否可以像下面那样简单地实现 Dispose 方法?
private bool objectDisposed;
public void Dispose()
{
if (!objectDisposed)
{
// Release/dispose managed resources
// ...
// ...
objectDisposed = true;
}
}
My First question is if a class does not implement a finalizer then
does the Dispose(bool) ever get called with parameter as false? (e.g.
by something in the CLR that I haven't come across)
否
Therefore, my second question is if a class does not need to implement
a finalizer then can it simply implement the Dispose method like
below?
我不会,但你可以。如果这样做,如果要扩展此 class,您将重新发明 IDisposable 模式。正如 HansPassant 在评论中指出的那样,如果有派生的 classes,IDisposable 模式会非常方便。我宁愿一开始就遵循这种模式。
基础class
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);
}
}
派生Class
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);
}
}
虽然 Dispose Pattern 在 Internet 和 SOF 上得到广泛讨论,但我找不到任何资源来回答我的问题。
因此,在将其标记为重复之前,请阅读到最后。如果您能指出我之前遗漏的问题,我会很乐意删除该问题。
我见过很多 class(盲目地?)在没有实现终结器的情况下实现处置模式。
MSDN article on Dispose Pattern 说:
The Boolean parameter disposing indicates whether the method was invoked from the IDisposable.Dispose implementation or from the finalizer. The Dispose(bool) implementation should check the parameter before accessing other reference objects (e.g., the resource field in the preceding sample). Such objects should only be accessed when the method is called from the IDisposable.Dispose implementation (when the disposing parameter is equal to true). If the method is invoked from the finalizer (disposing is false), other objects should not be accessed. The reason is that objects are finalized in an unpredictable order and so they, or any of their dependencies, might already have been finalized.
根据我的理解,GC 调用终结器方法(如果已实现),该方法又应调用参数为 false 的 Dispose(bool) 方法。
我的第一个问题是,如果 class 没有实现终结器,那么 Dispose(bool) 是否曾经被调用时参数为 false? (例如,在 CLR 中我没有遇到过)
我了解 Dispose(bool) 可用于确保对象仅被处理一次。
因此,我的第二个问题是,如果 class 不需要实现终结器,那么它是否可以像下面那样简单地实现 Dispose 方法?
private bool objectDisposed;
public void Dispose()
{
if (!objectDisposed)
{
// Release/dispose managed resources
// ...
// ...
objectDisposed = true;
}
}
My First question is if a class does not implement a finalizer then does the Dispose(bool) ever get called with parameter as false? (e.g. by something in the CLR that I haven't come across)
否
Therefore, my second question is if a class does not need to implement a finalizer then can it simply implement the Dispose method like below?
我不会,但你可以。如果这样做,如果要扩展此 class,您将重新发明 IDisposable 模式。正如 HansPassant 在评论中指出的那样,如果有派生的 classes,IDisposable 模式会非常方便。我宁愿一开始就遵循这种模式。
基础class
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);
}
}
派生Class
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);
}
}