我知道using
块确保被“使用”的IDisposable
对象将被放置在块的末尾 - 但保证该对象将在此之前不被处置?
换句话说,如果我有:
using (new DisposableObject()) {
// blah blah
}
我可以确定DisposableObject
在块结束之前不会被释放,或者垃圾收集器是否检测到我在块内没有处理它,并立即处理它?</ p>
答案 0 :(得分:6)
不,不。没有什么可以阻止你做的事情:
using(var myObject = new DisposableObject())
{
myObject.Dispose();
}
在这种情况下究竟会发生什么取决于DisposableObject
的语义。它可能会抛出异常,或者可能非常满意Dispose
被调用两次。
应该注意的是,对象处理和垃圾收集是完全不同的概念。仅仅因为一个对象被处理并不意味着它将被垃圾收集,并且仅仅因为一个对象被垃圾收集并不意味着它将被处理掉。
一旦对对象的所有引用都被破坏或无法访问,对象就可能被垃圾收集。当代码在using
- 块内运行时,这不会发生,因为块本身具有对该对象的引用。
答案 1 :(得分:4)
您的对象只会被丢弃一次,并且在使用块结束之前不会进行GC。
规范保证当你有using (expression) statement
并且表达式类型是可以为空的类型(称之为ResourceType
)时,它会扩展为:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
Dispose
将在块的末尾调用一次,并且有一个本地生成的,用于保持对一次性对象的引用。本地阻止对象在使用块结束之前进行GC。
答案 2 :(得分:2)
我认为您更愿意了解垃圾收集而不是处理。
垃圾收集器不会收集using
块内的对象。即使你专门调用Dispose
方法,仍然有一个活动的引用,所以它不会被收集。
为using
块生成的代码以检查对象是否可以处置结束,以便在using
块期间使用将使对象保持活动状态。