换一种说法,
class Foo
{
object obj;
Foo() { obj = new object(); }
~Foo() { obj.ToString(); /* NullReferenceException? */ }
}
Run Code Online (Sandbox Code Playgroud)
两个对象的终结器不保证以任何特定顺序运行,即使一个对象引用另一个对象.也就是说,如果对象A具有对象B的引用并且两者都具有终结器,则当对象A的终结器开始时,对象B可能已经完成.
简而言之,您不能在终结器期间对引用对象的状态做出任何假设.
几乎在所有情况下,终结器中实现的逻辑都属于Disposable模式.这是如何使用IDisposable接口在.NET中正确实现模式的示例.
public class MyClass : IDisposable
{
private bool _disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if(disposing)
{
// Release unmanaged resources.
}
// Release managed resources (Streams, SqlConnections, etc.)
}
_disposed = true;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您正在使用非托管资源,请查看本文以了解如何IDisposable使用终结器实现:
这不安全,因为obj可能已经被垃圾收集了.另请注意,垃圾收集器不会将引用设置为null.因此,即使检查obj!= null也无济于事.
详情请见:http: //msdn.microsoft.com/en-us/magazine/cc163392.aspx#S3
" 概括这个原则,在Dispose方法中,清除对象所持有的所有资源是安全的,无论它们是托管对象还是本机资源.但是,在终结器中清理不可最终化的对象是安全的,并且通常终结器应该只释放本机资源. "(你的obj是最终的,所以你不应该在另一个终结器中触摸它)
这也是你拥有的原因
如果(处置){...}
在IDisposable模式中(参见上面链接中的图2).
| 归档时间: |
|
| 查看次数: |
575 次 |
| 最近记录: |