我只能想到编译器自动调用 dispose 的两种情况;最明显的是:
using(var obj = ... )
{
// some code
}
这是一个明确的指令,说“最后,无论成功还是失败,如果obj
非空,则调用obj.Dispose()
”。基本上它扩展为:
{
var obj = ...
try {
// some code
} finally {
if(obj != null) obj.Dispose();
}
}
另一个是foreach
, where-by 迭代器被处理 - 虽然它变得有点复杂,因为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()
: 相同的事情,但可能不会。