管理されていないリソースを「所有する」クラスは、(そしてIDisposableを実装する)?

StackOverflow https://stackoverflow.com//questions/9657637

質問

私は OSS Project に働いています< href="http://mediainfo.sourceforge.net/en" rel="nofollow"> mediainfoライブラリ .NETで使いやすいですが、この質問は一般化できます。

派生クラス d が常にその基本クラス db のコンストラクタを呼び出すときにオブジェクト o をインスタンス化します。 DBはそのコンストラクタに送信されたものに値を設定しますが、値自体は db の基本クラス b で宣言されています。

  1. 「所有」 (下のコードのAKA Mediainfo)?
  2. .NETアプリケーションの場合、これらのうちどれがIDSposableを実装する必要がありますか? 注: o は管理されていないか、少なくとも管理対象のライブラリの周囲に包まれた管理対象オブジェクトのインスタンス化は、「 mediainfo.close()」の形式でクリーンアップを必要としています。 "。私はこれが「管理されていない」としてこのカウントを確実にしていません。

    明確にするのを助けるために、私に実際のコードを使わせてください:

    d db から派生します:

    // MediaFile is "D" 
    public sealed class MediaFile : GeneralStream
    {
        public MediaFile(string filePath)
            : base(new MediaInfo(), 0) {
            // mediaInfo is "O"
            mediaInfo.Open(filePath);
        }
    }
    
    .

    db b から派生した o

    // GeneralStream is "DB"
    public abstract class GeneralStream : StreamBaseClass
    {
        public GeneralStream(MediaInfo mediaInfo, int id) {
            this.mediaInfo = mediaInfo; // declared in StreamBaseClass
            // ...
        }
    }
    
    .

    b 宣言

    // StreamBaseClass is "B"
    public abstract class StreamBaseClass
    {
        protected MediaInfo mediaInfo; // "O" is declared
        // ...
    }
    
    .

役に立ちましたか?

解決

リソースへの参照を保持するオブジェクトを所有しています。

StreamBaseClassは参照mediaInfoを持ち、IDisposableを実装する必要があります。参照とDisposeメソッドは自動的に派生クラスによって継承されます。

他のヒント

クラスCがIDSPOOSABLEを実装する非公開ローカル変数Vである変数を所有している場合、CはIDSPOOSABLEであり、CのIDSPOOSABLEはvを配置する必要があります。

クラスDがネイティブリソースnを所有している場合、dはIDSPOOSABLE(n)とでもを持ちます。P>

このパターンをたどる場合は、IDSPOOSABLEを持つことがある場合は、常に()を廃棄する必要があります()、それはオブジェクトツリーのすべてをすべて削除します。しかし、誰かがあなたを忘れた場合にも(読み取り:同僚、あなたのライブラリーのユーザーなど)ネイティブリソースはD'Sファイナライザーによってクリーンアップされるため、オブジェクトを漏らすことはありません。

IDisposableの責任は、が作成するオブジェクトに属します。特に明示的な契約がない場合は、が作成します。逆の協定は、一般に、リソースの作成者が消費者の存続期間についてはわからない場合に使用されます。 ConstructorまたはFactoryメソッドが渡されたIDisposableの最後の消費者になる可能性がある場合、そのメソッドがDisposeの呼び出しを受け入れるかどうかを示すパラメータを受け入れるべきです。 NULL以外の場合、消費者がオブジェクトが必要なときに呼び出されます。オブジェクトの作成者が消費者を表示する場合は、NULLを渡すことができます。それがハンドオフされた後にCreatorがオブジェクトに使用されない場合は、オブジェクトのDisposeメソッドを渡すことができます。 Creatorが消費者を示すかどうかわからない場合は、オブジェクトがまだ必要かどうかを判断し、そうでない場合はDisposeを呼び出すメソッドを渡すことができます。

チェーンコンストラクターの中にIDisposableを構築することは、コールのレシピです(Try-Lock In Try-Lockで連鎖コンストラクタコールをラップする方法はありません)。あなたが何か安全にハンドルすること(例えば、連鎖コンストラクタではなく、または[threadstatic] Hackを使用することによって)それをハンドルすることになっていた場合、私はオブジェクトの作成者(派生クラス)がの一生を知ることになることを提案するでしょう。消費者(基本クラス)、所有権、およびクリーンアップの責任は、オブジェクト作成者に留まるべきです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top