最終的にはすべてが管理されていないリソースになります。
違います。フレームワークによってのみ管理 (割り当ておよび解放) される CLR オブジェクトによって使用されるメモリを除くすべて。
管理されていないリソースを保持していないオブジェクトを(直接または依存オブジェクトを介して間接的に)実装IDisposable
して呼び出すことは無意味です。オブジェクトの CLR メモリを自分で直接解放することはできないため、そのオブジェクトの解放を決定論的にすることはできません。メソッドレベルで直接使用される場合、値型はスタック操作によって割り当て/解放されるため、オブジェクトは参照型です。Dispose
GC
今では、誰もが自分の答えが正しいと主張しています。私の証明をさせてください。ドキュメントによると:
Object.Finalize メソッドを使用すると、オブジェクトはガベージ コレクションによって回収される前に、リソースを解放し、その他のクリーンアップ操作を実行できます。
Object.Finalize()
つまり、オブジェクトの CLR メモリは呼び出された直後に解放されます。[注: 必要に応じて、この呼び出しを明示的にスキップすることができます]
アンマネージ リソースのない使い捨てクラスを次に示します。
internal class Class1 : IDisposable
{
public Class1()
{
Console.WriteLine("Construct");
}
public void Dispose()
{
Console.WriteLine("Dispose");
}
~Class1()
{
Console.WriteLine("Destruct");
}
}
デストラクタFinalize
は、継承チェーンのすべてを暗黙的に呼び出すことに注意してください。Object.Finalize()
コンソール アプリのMain
メソッドは次のとおりです。
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Class1 obj = new Class1();
obj.Dispose();
}
Console.ReadKey();
}
呼び出しが決定論的な方法で管理Dispose
対象オブジェクトを解放する方法である場合、すべての「破棄」の直後に「破棄」が続きますよね? 何が起こるか自分の目で確かめてください。コマンド ライン ウィンドウからこのアプリを実行するのが最も興味深いです。
注:GC
現在のアプリ ドメインでファイナライズが保留されているすべてのオブジェクトを強制的に収集する方法がありますが、特定の 1 つのオブジェクトについてはそうではありません。Dispose
ただし、オブジェクトをファイナライズ キューに入れるために呼び出す必要はありません。アプリケーション全体のパフォーマンスが低下する可能性があるため、収集を強制することは強くお勧めしません。
編集
1 つの例外があります - 状態管理です。Dispose
オブジェクトがたまたま外部の状態を管理している場合、状態の変更を処理できます。状態が管理されていないオブジェクトでなくても、特別な扱いIDisposable
があるため、状態のように使用すると非常に便利です。例としては、セキュリティ コンテキストまたは偽装コンテキストがあります。
using (WindowsImpersonationContext context = SomeUserIdentity.Impersonate()))
{
// do something as SomeUser
}
// back to your user
WindowsImpersonationContext
内部でシステム ハンドルを使用するため、これは最良の例ではありませんが、画像は得られます。
要するに、実装するときIDisposable
は、メソッドで何か意味のあることを行う必要がある (または計画する) 必要があるということですDispose
。そうでなければ、ただの時間の無駄です。IDisposable
GC によるオブジェクトの管理方法は変わりません。