0

MSDN で次のコードを見つけました。

public class DisposeExample
{

    public class MyResource: IDisposable
    {    
        private IntPtr handle;
        private Component component = new Component(); 
        private bool disposed = false;

        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }

        public void Dispose()
        {
            Dispose(true);

            GC.SuppressFinalize(this);
        }


        protected virtual void Dispose(bool disposing)
        {
            if(!this.disposed)
            {

                if(disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }


                CloseHandle(handle);
                handle = IntPtr.Zero;

                disposed = true;

            }
        }

        ~MyResource()
        {
            Dispose(false);
        }
    }
    public static void Main()
    {
        MyResource obj = new MyResource()
        //obj.dispose()
    }
}

ここで混乱しているのは、obj.dispose を呼び出すと、クラス MyResources で作成されたオブジェクト、つまりハンドル、コンポーネントなどが破棄されることです。しかし、obj もヒープから削除されますか?? 同じことがデストラクタにも当てはまります。dispose を呼び出さないと、いつかデストラクタが呼び出されます。デストラクタ内のコードは、含まれているオブジェクトを削除します。しかし、オブジェクトはどうですか?第二に、クラス内でデストラクタが定義されておらず、dispose を呼び出すことさえしていない場合、GC はここに表示されませんか?

4

2 に答える 2

0

IDisposable で推奨する基本的なルールは、任意の時点で、IDisposable を実装するすべてのオブジェクトに対して、クリーンアップされることを保証するという明確に定義された責任を持つエンティティが 1 つだけ存在する必要があるということです (ほとんどの場合)。Dispose放棄される前に )を呼び出すことによって。そのような責任は、最初はオブジェクトのコンストラクターを呼び出すエンティティに属しIDidposableますが、そのエンティティは責任を他のエンティティに引き渡す場合があります (別のエンティティが再度引き渡す場合など)。

一般に、ほとんどのプログラマは、ファイナライザとデストラクタが存在しないふりをした方がよいと思います。それらは通常、コードが不十分に書かれた結果としてのみ必要とされ、ほとんどの場合、100% 正しいファイナライザー/デストラクタを作成し、スレッド化コンテキスト、偶発的な復活などに関連するすべてのトリッキーな問題に対処するために費やさなければならない労力です。 . 上記の主要なルールが常に守られるように、より適切に費やすことができます。フレームワークとその言語のいくつかの不幸な設計上の決定のため、ファイナライザ/デストラクタなしではうまく処理できない状況がいくつかありますが、ほとんどの場合、ファイナライザ/デストラクタは、比較的すぐに失敗するコードに変換するのに役立ちます。ほとんどの場合は機能しますが、デバッグがほとんど不可能な方法で失敗する場合があります。

于 2013-02-08T17:21:31.320 に答える
0

IDisposable exists to remove unmanaged items from your managed objects. The runtime automatically provides a destructor, this destructor here has the sole purpose of releasing unmanaged items. As soon as your object goes out of scope or is set to null and has no more references to it will eventually be cleared by the GC.

于 2013-02-08T08:04:42.917 に答える