コンパイラが自動的に dispose を呼び出すシナリオは 2 つしかないと思います。最も明白なのは次のとおりです。
using(var obj = ... )
{
// some code
}
これは、「最後に、成功または失敗にかかわらず、obj
null 以外の場合は呼び出すobj.Dispose()
」という明示的な指示です。基本的には次のように展開されます。
{
var obj = ...
try {
// some code
} finally {
if(obj != null) obj.Dispose();
}
}
もう 1 つはforeach
で、イテレータが破棄されます - 少し複雑になりますが、それが必要であることを指定していIEnumerator
ないIDisposable
ため (対照的に、それを指定している)、技術的には では必要でさえありませんが、基本的には次のとおりです。IEnumerator<T>
IEnumerable
foreach
foreach(var item in sequence) {
// some code
}
次のように表現できます (ただし、仕様では多少異なる場合があります)。
{
var iter = sequence.GetEnumerator();
using(iter as IDisposable)
{
while(iter.MoveNext())
{ // note that before C# 5, "item" is declared *outside* the while
var item = iter.Current;
// some code
}
}
}
それ以外の場合はすべて、リソースの処分はユーザーの責任です。
が確実に呼び出されない場合Dispose()
、GC が最終的にオブジェクトを収集するまで何も起こりません。ファイナライザーがある場合(存在する必要はなく、通常は存在しません)、ファイナライザーが呼び出されますが、それは とは異なりDispose()
ます。(型ごとの実装に応じて) : と同じことをDispose()
することになるかもしれませんが、そうではないかもしれません。