23

Microsoft.NET Frameworkは、メソッドIDisposableの実装を必要とするインターフェイスを提供しますvoid Dispose()IDisposableその目的は、実装が割り当てた可能性のある高価なリソースの手動またはスコープベースのリリースを可能にすることです。例には、データベースコレクション、ストリーム、ハンドルが含まれます。

私の質問は、Dispose()メソッドの実装がべき等である必要があるかどうかです。同じインスタンスで複数回呼び出された場合、インスタンスは1回だけ「破棄」され、後続の呼び出しは例外をスローしません。Javaでは、同様の動作をするオブジェクトのほとんど(ここでもストリームとデータベース接続が例として思い浮かびます)は、そのclose()操作に対してべき等であり、これはたまたまDispose()メソッドの類似物です。

ただし、.NET(および特にWindowsフォーム)に関する私の個人的な経験では、すべての実装(.NET Framework自体の一部)がべき等であるとは限らないため、これらを呼び出すと、がスローされObjectDisposedExceptionます。これは、使い捨てオブジェクトの実装にどのようにアプローチすべきかについて私を本当に混乱させます。シナリオに対する一般的な答えはありますか、それともオブジェクトの具体的なコンテキストとその使用法に依存していますか?

4

4 に答える 4

20

Dispose()メソッドの実装はべき等である必要があります

はい、そうすべきです。何回呼び出されるかはわかりません。

MSDNでのDisposeメソッドの実装から:

Disposeメソッドは、例外をスローせずに複数回呼び出すことができる必要があります。

の適切な実装を持つオブジェクトにはIDispose、すでに破棄されているかどうかを示すブールフィールドフラグがあり、後続の呼び出しでは何も実行されません(すでに破棄されているため)。

于 2012-01-19T09:45:22.577 に答える
7

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

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

}
于 2012-01-19T09:48:27.570 に答える
5

MSDNから:

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

于 2012-01-19T09:46:12.923 に答える
4

個人的に-はい-私は常にDispose()をべき等にします。

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

ただし、同様に、一部のアプリケーションでは、それほど明確ではない場合があります。

たとえば、デコレータのシナリオでは、別の使い捨てオブジェクトBで装飾された使い捨てオブジェクトAがある場合があります。Aを明示的に破棄したい場合でも、Dispose on Bは、ラップするインスタンスを破棄する場合もあります(ストリームと考えてください)。

Disposeをべき等にするのは比較的簡単です(つまり、すでに処分されている場合は何もしません)。そうしないのはばかげているようです。

于 2012-01-19T09:48:28.490 に答える