95

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

PS - 这只是一个好奇(睡得好,不是在生产代码中)。是的,我知道我可以ObjectDisposedException在尝试访问对象的成员时捕捉到。

4

8 回答 8

51

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

于 2008-10-10T16:48:16.327 回答
43

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

于 2008-10-10T16:49:02.113 回答
20

没有内置的东西可以允许这样做。您需要公开一个反映内部已处置标志的 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);
    }
}
于 2008-10-17T08:49:49.813 回答
9

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

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

于 2008-10-10T16:56:22.333 回答
1

我看到这是旧的,但我没有看到答案。并非所有一次性对象(如 DataSet)都具有可以附加的已处置事件。

class DisposeSample : IDisposable
{
    DataSet myDataSet = new DataSet();
    private bool _isDisposed;

    public DisposeSample()
    {
        // attach dispose event for myDataSet
        myDataSet.Disposed += MyDataSet_Disposed;
    }

    private void MyDataSet_Disposed(object sender, EventArgs e)
    {
        //Event triggers when myDataSet is disposed
        _isDisposed = true; // set private bool variable as true 
    }


    public void Dispose()
    {
        if (!_isDisposed) // only dispose if has not been disposed;
            myDataSet?.Dispose(); // only dispose if myDataSet is not null;
    }
}
于 2018-09-14T00:56:54.830 回答
1

Dispose方法需要在对象被放弃之前执行任何清理工作;如果不需要清理,则不需要执行任何操作。要求一个对象跟踪它是否已被释放,即使该Dispose方法不做任何事情,也将需要许多IDisposable对象添加一个标志,以获得非常有限的好处。

如果IDisposable包含两个属性可能会有所帮助 - 一个指示对象是否需要处置,其中一个指示对象没有被处置而变得无用。对于处理实际上做某事的对象,两个值最初都是 true,之后会变为 false Dispose。对于处理不需要进行任何清理的对象,第一个方法总是可以返回 false,而第二个方法总是返回 true,而不必在任何地方存储标志。不过,我认为现在无法将它们添加到 .NET 中。

于 2015-10-08T16:37:59.323 回答
0

检查对象是否使用 Extension 方法处理的快捷方式可能是

public static class ObjectExtensions 
{
    public static bool IsDisposed(this object obj)
    {
        try
        {
            obj.ToString();
            return false;
        }
        catch (ObjectDisposedException)
        {
            return true;
        }
    }

}

//Usage
if(myObject.IsDisposed()){ 
    /* Do your Stuff */ 
}
于 2021-07-29T06:56:35.933 回答
-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
于 2013-12-07T20:43:56.197 回答