我想听听您对以下主题的看法:
想象一下,我们有一个负责实现一个特定目的的方法,但要做到这一点,它需要大量本地范围对象的支持,其中许多都实现了IDisposable
.
MS 编码标准说,当使用IDisposable
不需要“存活”方法范围的本地对象时(不会返回或不会分配给某些较长寿命的状态信息object
),您应该使用该using
构造。
问题是,在某些情况下,您可以获得嵌套的“地狱”using
块:
using (var disposableA = new DisposableObjectA())
{
using (var disposableB = new DisposableObjectB())
{
using (var disposableC = new DisposableObjectC())
{
//And so on, you get the idea.
}
}
}
如果您使用的某些对象派生自一个公共基础或实现一个interface
实现IDisposable
. 这当然是以在需要对象的真实类型时必须强制转换所述对象为代价的。有时这可能是可行的,只要施法量不会失控:
using (var disposableA = new DisposableObjectA())
{
using (DisposableBaseObject disposableB = new DisposableObjectB(),
disposableC = new DisposableObjectC)
{
using (var disposableD = new DisposableObjectD())
{
//And so on, you get the idea.
}
}
}
另一种选择是不使用using
块并直接实现try-catch
块。这看起来像:
DisposableObjectA disposableA = null;
DisposableObjectB disposableB = null;
DisposableObjectC disposableC = null;
...
try
{
disposableA = new DisposableObjectA();
....
}
finally
{
if (disposableA != null)
{
disposableA.Dispose();
}
if (disposableB != null)
{
disposableB.Dispose();
}
//and so on
}
有趣的是,VS Code Analyzer 会将此代码标记为“错误”。它将通知您,并非所有可能的执行路径都能确保所有一次性对象都在超出范围之前被释放。我只能看到,如果在处理时抛出了某个对象,我认为这永远不会发生,如果确实发生了,这通常表明事情正在发生,你可能最好像你一样快速优雅地退出可以从您的整个应用程序中。
所以,问题是:你更喜欢哪种方法?using
不管有多少嵌套块总是更可取,或者超过一定限制,最好使用try-catch
块?