实施是一种良好的做法
IDisposable
如果你的类型资源匮乏,
但是
这只是
良好实践
和
无法由编译器强制
.
你能做的一件事就是虐待
不可分的
更值得注意的是
throw
或
assert
在
finalizer
(请记住,如果类型被正确地处理,则终结器
不会接到电话的
因为你会打电话的
GC.SuppressFinalize
在您的处置方法中)。当应用程序完成时,以下程序在调试器的输出窗口中显示错误,原因是
Hog
未正确释放。
class Program
{
static void Main(string[] args)
{
new Hog( ) ;
}
}
class Hog : IDisposable
{
public void Dispose( )
{
Dispose( true ) ;
GC.SuppressFinalize( this ) ;
}
protected virtual void Dispose( bool disposing )
{
GC.SuppressFinalize( this );
}
~Hog( )
{
Debug.Fail( @"You didn't dispose me!" ) ;
Dispose( false ) ;
}
}
您将在调试器中看到以下错误:
---- DEBUG ASSERTION FAILED ----
---- Assert Short Message ----
You didn't dispose me!
---- Assert Long Message ----
at Hog.Finalize()
但是
,如果正确使用一次性物品,例如:
static void Main(string[] args)
{
using (new Hog())
;
}
…你什么也看不见。
为了使事情更有用,您可以在构造函数中记录当前堆栈跟踪并将其转储到析构函数中。所以新的,更有用的
猪
看起来像:
class Hog : IDisposable
{
readonly StackTrace _stackTrace ;
public Hog( )
{
#if DEBUG
_stackTrace = new StackTrace();
#endif
}
public void Dispose( )
{
Dispose( true ) ;
GC.SuppressFinalize( this ) ;
}
protected virtual void Dispose( bool disposing )
{
GC.SuppressFinalize( this );
}
~Hog( )
{
#if DEBUG
Debug.WriteLine("FinalizableObject was not disposed" + _stackTrace.ToString());
#endif
Dispose( false ) ;
}
}
在调试器输出窗口中使用它(而不处理它)可以得到:
FinalizableObject was not disposed at ConsoleApplication1.Hog..ctor()
at ConsoleApplication1.Program.Main(String[] args)
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()