Как определить, находится ли ссылка на объект IDisposable?

Есть ли способ или какой-либо другой легкий способ проверить, ссылается ли ссылка на расположенный объект?

P.S. - Это просто любопытство (хорошо спите, а не в производственном коде). Да, я знаю, что могу поймать ObjectDisposedException при попытке получить доступ к члену объекта.

Ответ 1

Это зависит от того, есть объекты IDisposable, которые позволяют вызвать метод Dispose столько, сколько вы хотите, и есть IDisposable объекты, которые бросают ObjectDisposedException. В таком случае эти объекты должны отслеживать состояние (обычно реализуемое с помощью частного булевского поля isDisposed).

Ответ 2

Нет - реализация IDisposable шаблона по умолчанию не поддерживает его

Ответ 4

В этом нет ничего, что позволит это. Вам нужно будет открыть логическое свойство 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);
    }
}

Ответ 5

Если это не ваш класс, и он не предоставляет свойство IsDisposed (или что-то подобное - это просто соглашение), то вы не можете узнать.

Но если это ваш класс, и вы следуете канонической реализации IDisposable, то просто выставляете поле _disposed или _isDisposed в качестве свойства и проверяете что.

Ответ 6

Метод Dispose необходим для выполнения любой очистки, необходимой для отказа объекта; если никакой очистки не требуется, ничего не нужно делать. Требование того, чтобы объект отслеживал, был ли он удален, даже если метод Dispose в противном случае ничего не сделал бы, потребовал бы, чтобы многие объекты IDisposable добавляли флаг для очень ограниченной выгоды.

Возможно, было бы полезно, если IDisposable включил два свойства - одно из которых указывало, нужен ли объект для утилизации, а один из них указывал на то, что объект не был бесполезен при удалении. Для объектов, где утилизация фактически что-то делает, оба значения будут изначально истинными и станут ложными после Dispose. Для объектов, в которых утилизация не требует никакой очистки, первый метод всегда может возвращать значение false, а второе - всегда, без необходимости хранить флаг в любом месте. Однако я не думаю, что они могут быть добавлены в .NET.

Ответ 7

То, что мне нравится делать, - объявить объекты без их инициализации, но установить их значения по умолчанию 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