2008-10-10 84 views
71

是否有一个方法,或一些其它重量轻的方式,检查是否一个引用是对已释放的对象?如何判断是否放置了一个IDisposable对象引用?

P.S. - 这只是一个好奇心(睡眠不好,不在生产代码中)。是的,我知道我可以在试图访问对象的成员赶上ObjectDisposedException

+10

邓诺。似乎好奇的是,没有`bool IsDisposed {get; }`System.IDisposable`声明。 – nicodemus13 2012-08-09 12:30:16

+2

@ nicodemus13:`Dispose`方法指示一个对象释放已获取但尚未释放的所有资源。如果一个对象从不拥有资源,那么它的`Dispose`方法通常不需要做任何事情;如果该类型声明`void IDisposable.Dispose(){};`否则它可以忽略`IDisposable`而没有每个实例的开销。一个`IsDisposed`属性在任何`Dispose`调用之后预期会变为真,将需要向否则可能会忽略Dispose的许多类型的每个实例添加否则不需要的布尔标志。 – supercat 2013-12-07 22:54:08

+0

但是,无论您在实现“IDisposable”的对象上调用某个方法,您如何检查它是否先被处置?而不是假设它不是和捕捉异常?或者不知何故,你的意图是管理一生,这样你就应该知道它是否被处置了? – nicodemus13 2013-12-16 14:30:33

回答

-17

这要看,有IDisposable对象,允许调用Dispose方法,只要你想尽可能多,并且有IDisposable对象抛出ObjectDisposedException。在这些对象必须跟踪的状态这样的情况下(通常是用私有布尔型字段isDisposed实现)。

40

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

9

如果不是你的类,它不提供IsDisposed财产(或类似的东西 - 这个名字仅仅是一个惯例),那么你就没有办法知道。

但是,如果这是您的课程,并且您遵循canonical IDisposable implementation,那么只需将_disposed或_isDisposed字段作为属性公开并检查。

16

没有什么内置的,将允许这一点。您需要公开一个反映内部处置标志的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); 
    } 
} 
-1

我喜欢做的是没有初始化他们申报的对象,但设置它们的默认值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 
2

是必需的Dispose方法来执行任何清理将REQ在物体被抛弃之前使用;如果不需要清理,则不需要执行任何操作。需要一个对象来跟踪它是否已被释放,即使Dispose方法,否则什么都不做,就需要很多IDisposable对象添加标志非常有限的益处。其中一个所指示的对象是否需要处置,和其中一个表示,该对象一直没通过处置形同虚设 -

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

相关问题