2009-03-07 3 views

答えて

9

ILでのファイナライザが常にある - System.Object.Finalize()は、すべてのクラスに存在するので、あなたは、カスタムクラスを作成する場合、それはあなたが抑制したいファイナライザを持っています。つまり、すべてのオブジェクトがファイナライズキューに置かれるわけではないので、独自のファイナライザを実装する場合、技術的にはファイナライズを抑制する必要があります。

IDisposableを実装して、アンマネージリソースをラップする場合は、ファイナライザを含める必要があります。理論上は、Disposeが呼び出されたときに、すでにクリーンアップを行っています。

+0

真。また、Dispose()を呼び出すファイナライザが必要です。 – configurator

+0

True- Object.Finalizeはnull演算ですが、IDisposableを実装している場合は、解放するためのリソースがあるといえます。 MSDNからは、それらを解放するファイナライザが常に必要なので、正しく処理されることを意味します。これは、ファイナライズコールのDisposeとDisposeの抑止の終了を意味します。 –

+4

@ configurator管理されていないリソース(ハンドルなど)を直接所有している場合のみファイナライザが必要です。間接的にしか所有していない場合、たとえばFileStreamへの参照、なぜあなたはIDisposable.Dispose(){if(fs!= null){fs.Dispose();以上のものを書くべきですか? fs = null; }}? IMO、StyleCopは役に立たないテキストをたくさん書いて維持することを強いるひどいツールであり、その代わりにビジネス価値を追加しません。 –

2

すべてのオブジェクトには、c#デストラクタ(実際にはGCによって呼び出されることは保証されていません)を使用してオブジェクトを実装していない場合でも、ファイナライザメソッドがあります。 IDisposableを実装している場合は、呼び出しを抑止することをお勧めします。これは、ファイナライゼーションを明示的に実行することを決定したためです。

devx article

+0

"GCによって呼び出される保証はありません"と説明してください。 –

+0

プログラムの終了時に、クリーンアップに時間がかかりすぎると、ファイナライザを実行する機会がなくなることがあります。それは彼が指しているものかもしれません。 –

+0

はい、それは私が言及したものです。 – x0n

2

ファイナライザが定義されていない場合、SuppressFinalize()を呼び出す必要はありません。あなたが防御を望むなら、ファイナライザとDispose()を持つのが良いかもしれないので、常にDispose()を呼び出すためにクライアントに頼る必要はありません。それで、あなたが忘れてしまったときにリソースを漏らさないでしょう

+0

オブジェクトが他のIDisposableオブジェクトを「担当」していても、それ自体で管理されていないリソースがない場合は、Disposeは必要ですがFinalizerは必要ありません。 –

20

ない限り処分にGC.SuppressFinalize(this)をコールする必要は、ありません:あなたは(再び、それもここにあなたの責任ではないかもしれませんオーバーライドを意図した仮想のDisposeメソッドを実装する基底クラスですが、あなたが望むかもしれない

  • その場合に行う)
  • ファイナライザがあります。技術的には、.NETのすべてのクラスは、ファイナライザを持っていますが、唯一のファイナライザの存在はObjectの1である場合は、そのオブジェクトはファイナライズが必要とは考えられないとGC

I時にファイナライズリストに入れていません上記のいずれのケースもないと仮定すると、そのメッセージを無視しても問題ありません。

+1

派生クラス*はいつまでにファイナライザを単純な基本クラスに追加する必要がありますか?派生クラスが決して実行してはならないことを行うためのコードを追加するのはなぜですか? – supercat

+0

@supercat派生クラスが管理されていないリソースを所有している場合、それらが解放されることを保証するファイナライザが必要です。オブジェクトが常に正しく使用されている場合(try-finallyまたは同等の方法で)、Disposeはクリーンアップを実行してファイナライザを抑制しますが、ファイナライザは最終的に(オブジェクトがガベージコレクトされたとき)たとえDisposeが呼び出されていなくても(例外やコードブロックを保護することができないなど) –

+1

@TheDag:ファイナライザのクリーンアップを必要とする各アンマネージドリソースは、ほとんどの場合、 'Object'か、そのようなクリーンアップを支援するために明示的に設計された抽象基本型から派生しなければならない独自のオブジェクト内にカプセル化されるべきです。その結果得られる型は、参照がより大きな型によって保持される管理されたリソースになります。ファイナライズクリーンアップは、より小さなカプセル化オブジェクトによって処理されます。より大きいオブジェクトはファイナライザを必要としません。 – supercat

関連する問題