web-dev-qa-db-ja.com

IDisposableオブジェクト参照が破棄されているかどうかはどのようにわかりますか?

参照が破棄されたオブジェクトを参照しているかどうかを確認する方法、または他の軽量な方法はありますか?

追伸-これは単なる好奇心です(本番コードではなく、よく眠ってください)。はい、オブジェクトのメンバーにアクセスしようとするとObjectDisposedExceptionをキャッチできることを知っています。

80

いいえ-IDisposableパターンのデフォルト実装ではサポートされていません

45
Dandikas

_System.Windows.Forms.Control_には IsDisposed プロパティがあり、これは Dispose()が呼び出された後にtrueに設定 です。独自のIDisposableオブジェクトでは、同様のプロパティを簡単に作成できます。

38
Ryan Lundy

これを可能にするものは何も組み込まれていません。内部破棄フラグを反映する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);
    }
}
18
Scott Dorman

クラスではなく、IsDisposedプロパティ(または同様のもの-名前は単なる規則です)を提供しない場合は、知る方法がありません。

しかし、それがあなたのクラスであり、 正規のIDisposable実装 に従っている場合は、_disposedまたは_isDisposedフィールドをプロパティとして公開し、それを確認します。

9
jop

Disposeメソッドは、オブジェクトが破棄される前に必要なクリーンアップを実行するために必要です。クリーンアップが必要ない場合は、何もする必要はありません。 Disposeメソッドが何もしない場合でも、オブジェクトが破棄されたかどうかを追跡するためにオブジェクトを必要とする場合、非常に限定された利点のためにフラグを追加する多くのIDisposableオブジェクトが必要になります。

IDisposableに2つのプロパティが含まれていると便利な場合があります。1つはオブジェクトが破棄する必要があるであるかどうかを示し、もう1つはオブジェクトが廃棄により。実際に処分が何かを行うオブジェクトの場合、両方の値は最初は真であり、Disposeの後に偽になります。処分でクリーンアップを行う必要がないオブジェクトの場合、最初のメソッドは常にfalseを返し、2番目のメソッドは常にtrueを返すことができ、フラグをどこにも格納する必要はありません。しかし、それらを.NETに追加する方法は今のところないと思います。

2
supercat

これは古いと思いますが、答えはありませんでした。 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;
    }
}
1
Moses