"using"语句是否总是会释放对象?

34

即使在 using 语句中有返回或抛出异常,它是否总是处理对象?例如:

using (var myClassInstance = new MyClass())
{
    // ...
    return;
}
或者
using (var myClassInstance = new MyClass())
{
    // ...
    throw new UnexplainedAndAnnoyingException();
}
3个回答

43

是的,这就是整个重点。它可以编译成:

SomeDisposableType obj = new SomeDisposableType();
try
{
    // use obj
}
finally
{
    if (obj != null) 
        ((IDisposable)obj).Dispose();
}

在这里要注意术语的使用,对象本身并没有被释放。通常会调用Dispose()方法来释放非托管资源。


有一些情况下,finally块不会像我在答案中解释的那样执行。 - yakya

14

不,它并不会。

但这并不是using语句的。而是由于CLR如何处理finally块的原因。有一些情况下,finally块将不会执行。如果您有一个未处理的异常,并且如果CLR 认为执行更多的代码会导致更多的错误,它将不会执行Dispose方法(因为它不会执行finally块,而Dispose方法编译成了该块...)。因此,请非常小心,不要将自己的生命寄托在执行Dispose方法上。

导致Dispose方法未被执行的其他情况可以列举如下:


4
电力损耗...真的吗? - malat
1
真的。例如,电力不会等待一个糟糕实现的“Dispose”方法完成,以保持持久层处于良好状态。 - yakya
3
是的,电力损失。 - ispiro

10

如果对象实现了IDisposable接口,它将被调用。

来自MSDN的使用语句(C#参考)。

定义一个范围,在该范围之外,一个或多个对象将被释放。

使用using语句允许程序员指定使用资源的对象在何时释放它们。提供给using语句的对象必须实现IDisposable接口。该接口提供了Dispose方法,应该释放对象的资源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接