参照が破棄されたオブジェクトへの参照であるかどうかを確認する方法、またはその他の軽量な方法はありますか?
PS - これは単なる好奇心です (製品コードではなく、よく眠ってください)。はい、ObjectDisposedException
オブジェクトのメンバーにアクセスしようとすると をキャッチできることはわかっています。
参照が破棄されたオブジェクトへの参照であるかどうかを確認する方法、またはその他の軽量な方法はありますか?
PS - これは単なる好奇心です (製品コードではなく、よく眠ってください)。はい、ObjectDisposedException
オブジェクトのメンバーにアクセスしようとすると をキャッチできることはわかっています。
いいえ - IDisposable パターンのデフォルトの実装ではサポートされていません
System.Windows.Forms.Control
が呼び出された後に true に設定されるIsDisposed
プロパティがあります。独自の IDisposable オブジェクトで、同様のプロパティを簡単に作成できます。Dispose()
これを可能にするものは組み込まれていません。内部のdisposedフラグを反映する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
2 つのプロパティが含まれていると便利だったかもしれません。廃棄が実際に何かを行うオブジェクトの場合、両方の値は最初は true で、後に false になりますDispose
。破棄でクリーンアップを行う必要がないオブジェクトの場合、最初のメソッドは常に false を返し、2 番目のメソッドは常に true を返すことができ、フラグをどこにも保存する必要はありません。ただし、現在、それらを .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