如果Base
是你自己的类,那么不要实现这个反模式。
Dispose
当一个类同时包含必须释放的托管资源(例如,应该有自己调用的 Stream 对象)和必须清理的非托管资源时,使用双重处理(如果处理为真,则为假) 。向上。
这是一个坏主意。而是让您的所有课程都属于一两个类别:
A. 只有非托管资源的类。理想情况下,每个班级只有一个:
public sealed class HandlesUnmanaged : IDisposable
{
private IntPtr _someUnmanagedHandleOfSomeKind;
public string DoSomething(string someParam)
{
// your useful code goes here;
// make it thin, non-virtual and likely to be inlined
// if you need to extend functionality, but it in a
// containing Disposable class, not a derived class.
}
private void CleanUp()
{
//your code that cleans-up someUnmanagedHandleOfSomeKind goes here
}
public void Dispose()
{
CleanUp();
GC.SuppressFinalize(this);//finaliser not needed now.
}
~HandlesUnmanaged()//not called if already disposed
{
CleanUp();
}
}
理想情况下,您甚至不需要像这样的任何类,而是使用SafeHandle
which 为您做这些。
B. 具有一个或多个需要处置的托管资源的类:
public class NoUnmanaged : IDisposable
{
private HandlesUnmanaged _likeAbove;
private Stream _anExampleDisposableClass;
public virtual void Dispose()
{
_likeAbove.Dispose();
_anExampleDisposableClass.Dispose();
}
/* Note no finaliser, if Dispose isn't called, then _likeAbove's
finaliser will be called anyway. All a finaliser here would do is
slow things up and possibly introduce bugs.
*/
}
public class DerivedNoUnManaged : NoUnmanaged
{
Stream _weMayOrMayNotHaveAnotherDisposableMember;
public override void Dispose()
{
//note we only need this because we have
//another disposable member. If not, we'd just inherit
//all we need.
base.Dispose();
weMayOrMayNotHaveAnotherDisposableMember.Dispose();
}
}
总之,我们要么有简单的非托管拥有类,它们在它们Dispose()
和它们的终结器中做同样的事情,除了前调用GC.SuppressFinalize
,或者我们有简单的非非托管拥有类,它们只是Dispose()
他们需要处理的所有东西,包括如有必要,请致电base.Dispose()
,并且没有终结者。无需将逻辑拆分为同一类中的两种类型。终结者没有风险调用已经终结的东西,或者强制超过必要的东西进入终结队列。
理想情况下,你甚至根本不做第一种类型。只是第二种。
如果您通过从另一方的类继承而被迫进入它,那么只需执行以下操作:
public MyClass : Base
{
Stream _forExample;
public override void Dispose(bool disposing)
{
if(disposing)
{
_forExample.Dispose();
}
base.Dispose(disposing);
}
}
不要disposing == false
自己处理这种情况,因为那里没有混入非托管资源。