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