如果Base
是你自己的类,那么不要实现这种反模式。
当一个类同时包含必须处理的托管资源(例如应该拥有它自己的Dispose
的Stream对象)和非托管资源时,使用双重处置(如果处置为true,则为false)必须清理。
这是一个坏主意。相反,您的所有课程都适合一个或两个类别:
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
这确实是给你的。
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()
及其finaliser ,但前者呼叫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
情况下,由于没有混在里面非托管资源。
你能展示更多'MyData'吗? – 2012-08-03 12:40:52
“Base”是你自己的班级,还是来自第三方的班级? – 2012-08-03 12:41:20
您是否真的需要使用Dispose(bool)方法,通常只有在您确实需要释放非托管资源时才需要这种方法。 – CodingGorilla 2012-08-03 12:44:16