1

すべてのクラスで Dispose パターンを再コーディングする代わりに、 DisposableBase 基本クラスを使用することで、キャッチまたは隠れた問題はありますか?

なぜ誰もがそのような関連クラスを使用しないのですか?

編集

  1. 当然、IDisposable を実装するクラスのみを意味していました

  2. 継承のオプションを使い果たしていることはわかっていますが、代償を払うつもりです (少なくともできる限り、それ以外の場合は害がない場合)。

  3. クラスを封印できるときはそうしますが、継承階層のベースを使い捨てにしたい場合があります。

4

3 に答える 3

2

すべてのクラスに Dispose() を実装する必要はありません。決定論的なクリーンアップが必要なものだけです。使い捨て可能な基本クラスに関して、それが多くを提供するかどうかは完全にはわかりません-IDisposable複雑なインターフェースではありません。主に役立つのは、アンマネージ リソースを処理していて、ファイナライザーが必要な場合ですが、それでもそれほど多くのコードではありません。

個人的には、そのような基本クラスは気にしません。特に、(単一継承の世界での) 継承は非常に急速に制限的になります。しかし、もっと重要なことは、メソッドをオーバーライドすることは、単純に public Dispose() メソッドを提供することと大差ありません。

繰り返しますが、管理されていないオブジェクトを処理している場合は、ファイナライザーなどが必要です。

これら (管理されていないリソース) がたくさんある場合は、PostSharpに作業を任せられるかどうかを確認できます。すでに存在するかどうかはわかりませんが、(特に) ファイナライザーなどを処理するアスペクトを作成できる可能性があります。

于 2008-11-10T13:09:37.150 に答える
2

まあ、それは継承の1つのオプションを使い果たして、クラスの1つの側面を記述します-それは理想的ではありません、IMO。DisposableHelper への参照があり、IDisposable の実装が helper.Dispose を呼び出すだけのコンポジションで何かをしようとするのは興味深いでしょう。これには、残りのボイラープレート ロジックが含まれています。コールバック デリゲート。うーん。サブクラスは、保護された Disposing イベントをサブスクライブして、「何かをする必要がある」ことを登録できます...しばらく検討する価値があるかもしれません。

個人的には、IDisposable を問題になるほど頻繁に実装しているとは思いません。そうするときは、とにかくクラスを封印するので、パターンの半分は問題になりません。

于 2008-11-10T13:12:00.683 に答える
1

Marc Gravellが言ったように、アンマネージドオブジェクトを処理している場合にのみファイナライザーが必要です。廃棄、ファイナライズ、およびリソース管理のガイドラインのセクション1.1.4の理由に従って、基本クラスに不要なファイナライザーを導入することはお勧めできません。

パフォーマンスとコードの複雑さの両方の観点から、ファイナライザーを備えたインスタンスに関連する実際のコストがあります。...ファイナライズは、割り当て時に各ファイナライズ可能なオブジェクトを特別なファイナライザー登録キューに配置する必要があるため、オブジェクトの存続期間のコストと期間を増加させます。基本的に、オブジェクトを参照するための追加のポインターサイズのフィールドが作成されます。さらに、このキュー内のオブジェクトは、GC中にウォークされ、処理され、最終的に、GCがファイナライザーを実行するために使用するさらに別のキューにプロモートされます。ファイナライズ可能なオブジェクトの数を増やすことは、より多くのオブジェクトがより高い世代に昇格すること、およびGCがキューをウォークし、ポインターを移動し、ファイナライザーを実行するために費やす時間の増加に直接関係します。また、オブジェクトの状態をより長く保つことにより、

SafeHandle (および関連するクラス)を使用する場合、DisposableBaseから派生するクラスをファイナライズする必要はほとんどありません。

于 2008-11-10T15:13:00.300 に答える