2012-01-19 7 views
19

Microsoft.NETフレームワークはvoid Dispose()メソッドの実装を必要とするIDisposableインターフェイスを提供します。その目的は、IDisposableの実装が割り当てていた高価なリソースの手動またはスコープベースの解放を有効にすることです。例には、データベースコレクション、ストリーム、およびハンドルが含まれます。IDisposable.Dispose()の実装は冪等でなければなりませんか?

Dispose()メソッドの実装は、同じインスタンスに対して複数回呼び出されると、一度だけ '廃棄'されるインスタンスとその後に例外をスローしないように呼び出されます。 Javaでは、同様の動作(ストリームとデータベース接続も例として私の頭に浮かんでいます)を持つオブジェクトのほとんどは、Dispose()メソッドのアナログであるclose()オペレーションの冪等です。

しかし、私の個人的な.NETでの経験(特にWindowsフォーム)、これらへの後続の呼び出しがObjectDisposedExceptionを投げるように(NETフレームワーク自体の一部である)ではないすべての実装は、冪等であることを示しています。これは、使い捨てオブジェクトの実装にどのようにアプローチするべきかについて私を本当に混乱させます。このシナリオに共通の答えがあるのですか、それはオブジェクトの具体的なコンテキストとその使用方法に依存していますか?

答えて

18

Dispose()方法の実装は

を冪等されるべきではい、それがすべきです。それが何回呼び出されるかは何も知られていません。 MSDNのImplementing a Dispose Methodから

Disposeメソッドは例外をスローせずに呼び出し可能な複数回にする必要があります。

それはすでにのと後続の呼び出しの上に配置されている場合IDisposeの良い実装を持つオブジェクトが示すブール値フィールドフラグを持つことになります(それが既に配置されたように)何もしません。

+7

マイクロソフトが常に自分の推奨に従っているとは限らないという理由だけで、あなたがすべきことではありません。 – linkerro

+0

@linkerro - あなたのやや謎めいたコメントを広げてください。 – Oded

+0

コントロールを2回ディスポーザルした場合、WinFormsが例外をスローすることを彼が指しているのだろうかと思います。 – DaveShaw

5

From MSDN:

Disposeメソッドが例外をスローせずに複数回呼び出すことができるようにします。このメソッドは、最初の呼び出しの後に何もしないでください。

+3

「リソースがすでに破棄されているときに、このタイプのインスタンスメソッドからDispose以外のObjectDisposedExceptionをスローする」このルールはDisposeメソッドには適用されません。例外をスローします。 – Jamiec

7

はい、オブジェクトが既に破棄されているときに呼び出されると、クラスの他のメソッドが正しく応答することも確認してください。

public void SomeMethod() 
{ 
    if(_disposed) 
    { 
     throw new ObjectDisposedException(); 
    } 
    else 
    { 
     // ... 
    } 

} 
+0

ここで対処できるのは、単に例外をスローすることです。何かが必要なのかどうかは本当に分かりません。配置されたオブジェクトが何らかの形でまだ「動作」する必要はありません。破棄されたオブジェクトを使用しようとするとバグであり、そのように扱われるべきです。 –

+0

@ R.MartinhoFernandes - はい、まだ追加するものです。 –

+0

@ R.MartinhoFernandes、私は@Emoが言っていると思います - あなたがまだ配置されているオブジェクトへの参照をまだ持っていれば、これらのメソッドは、 'ObjectDisposedException'をスローするか、そうでなければ、この状態に対して操作が不正であることを呼び出し側に通知する必要があります。残念ながら、私はこれがsinchronization意識の賞に来るかもしれないと信じています。 –

3

個人的に - はい - 私はいつもDispose()を冪等にします。

特定のアプリケーションのオブジェクトの通常のライフサイクルの間に、作成から廃棄までのライフサイクルは決定論的でよく知られている場合があります。

しかし、同じように、一部のアプリケーションではそれほど明確ではないかもしれません。

たとえば、デコレータのシナリオでは、別の使い捨てオブジェクトBで飾られた使い捨てオブジェクトAがあるかもしれません。Aを明示的に処分したいが、Bでも処分することもできます。ストリーム)。

却下棄権(つまり既に処分されている場合は何もしない)を行うことは比較的簡単ですが、それは愚かではないようです。

関連する問題