Как определить, находится ли ссылка на объект IDisposable?
Есть ли способ или какой-либо другой легкий способ проверить, ссылается ли ссылка на расположенный объект?
P.S. - Это просто любопытство (хорошо спите, а не в производственном коде). Да, я знаю, что могу поймать ObjectDisposedException
при попытке получить доступ к члену объекта.
Ответы
Ответ 1
Это зависит от того, есть объекты IDisposable
, которые позволяют вызвать метод Dispose
столько, сколько вы хотите, и есть IDisposable
объекты, которые бросают ObjectDisposedException
. В таком случае эти объекты должны отслеживать состояние (обычно реализуемое с помощью частного булевского поля isDisposed
).
Ответ 2
Нет - реализация IDisposable шаблона по умолчанию не поддерживает его
Ответ 3
System.Windows.Forms.Control
имеет свойство IsDisposed
, которое установлено true после Dispose()
называется. В ваших собственных объектах 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