如何判断是否放置了一个IDisposable对象引用?

有没有一种方法或其他一些轻量级的方法来检查引用是否是一个处置对象?

聚苯乙烯 – 这只是一个好奇(睡得好,不在生产代码)。 是的,我知道我可以在尝试访问对象的成员时捕获ObjectDisposedException

这取决于,有一些IDisposable对象可以根据需要调用Dispose方法,还有一些抛出ObjectDisposedException IDisposable对象。 在这种情况下,这些对象必须跟踪状态(通常使用私有布尔字段isDisposed来实现)。

否 – IDisposable模式的默认实现不支持它

System.Windows.Forms.Control有一个IsDisposed属性, 在调用Dispose()后设置为true 。 在您自己的IDisposable对象中,您可以轻松创build一个类似的属性。

没有什么可以做到的。 您需要公开一个反映内部处置标志的IsDisposed布尔属性。

 public class SimpleCleanup : IDisposable { private bool disposed = false; public bool IsDisposed { get { return disposed; } } public SimpleCleanup() { this.handle = /*...*/; } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { // free only managed resources here } // free unmanaged resources here disposed = true; } } public void Dispose() { Dispose(true); } } 

如果它不是你的类,它不提供一个IsDisposed属性(或类似的名称只是一个约定),那么你无法知道。

但是,如果它是你的类,而且你正在遵循规范的IDisposable实现 ,那么只需将_disposed或_isDisposed字段作为属性公开并检查。

Dispose方法需要在放弃对象之前执行所需的清理操作。 如果不需要清理,则不需要做任何事情。 要求对象跟踪它是否已经被处置,即使当Dispose方法否则什么也不做时,将需要许多IDisposable对象来添加一个标志,这是非常有限的。

如果IDisposable包含两个属性,可能会有所帮助,一个属性表示一个对象是否需要处置 ,另一个表示该对象没有被废弃处理。 对于处置实际上有所作为的对象,这两个值最初都是真实的,并且在Dispose后会变成错误的。 对于不需要清理的对象,第一种方法可以总是返回错误,第二种方法总是正确的,而不必在任何地方存储标志。 不过,我不认为现在有什么方法可以添加到.NET中。

我喜欢做的是声明对象,而不是初始化它们,但将其默认值设置为Nothing 。 然后,在循环结束时,我写道:

 If anObject IsNot Nothing Then anObject.Dispose() 

这是一个完整的示例:

 Public Sub Example() Dim inputPdf As PdfReader = Nothing, inputDoc As Document = Nothing, outputWriter As PdfWriter = Nothing 'code goes here that may or may not end up using all three objects, ' such as when I see that there aren't enough pages in the pdf once I open ' the pdfreader and then abort by jumping to my cleanup routine using a goto .. GoodExit: If inputPdf IsNot Nothing Then inputPdf.Dispose() If inputDoc IsNot Nothing Then inputDoc.Dispose() If outputWriter IsNot Nothing Then outputWriter.Dispose() End Sub 

这也适用于将主要对象放在例程顶部,在Try例程中使用它们,然后将它们放置在Finally块中:

 Private Sub Test() Dim aForm As System.Windows.Forms.Form = Nothing Try Dim sName As String = aForm.Name 'null ref should occur Catch ex As Exception 'got null exception, no doubt Finally 'proper disposal occurs, error or no error, initialized or not.. If aForm IsNot Nothing Then aForm.Dispose() End Try End Sub