There are only two scenarios I can think of where the compiler automatically calls dispose; the most obvious would be:
using(var obj = ... )
{
// some code
}
which is an explicit instruction to say "at the end, whether success or failure, if obj
is non-null, call obj.Dispose()
". Basically it expands to:
{
var obj = ...
try {
// some code
} finally {
if(obj != null) obj.Dispose();
}
}
The other is foreach
, where-by the iterator is disposed - although it gets a bit complicated, because IEnumerator
doesn't specify that IDisposable
is required (by contrast, IEnumerator<T>
does specify that), and technically IEnumerable
is not even required for foreach
, but basically:
foreach(var item in sequence) {
// some code
}
could be expressed as (although the spec may say it slightly differently):
{
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
}
}
}
In all other cases, disposing resources is your responsibility.
If you don't ensure that Dispose()
is called, then nothing will happen until GC eventually collects the object; if there is a finalizer (there doesn't have to be, and usually isn't), the finalizer will be invoked - but that is different to Dispose()
. It may (depending on the per-type implementation) end up doing the same thing as Dispose()
: but it may not.