快速示例以说明:
using (new Tag("body")) {
Trace.WriteLine("hello!");
}
// ...
class Tag : IDisposable {
String name;
public Tag(String name) {
this.name = name;
Trace.WriteLine("<" + this.name + ">");
Trace.Indent();
}
public void Dispose() {
Trace.Unindent();
Trace.WriteLine("</" + this.name + ">")
}
}
构造函数定义了起始部分,Dispose 方法定义了结束部分。
然而,尽管看起来很有吸引力,但这种结构存在一个严重的缺点,即 Dispose 方法是在 finally 块内调用的。因此,存在两个问题:
应避免在 finally 块中抛出异常,因为它们会覆盖本应被捕获的原始异常。
无法在 Dispose 方法中知道在“开始”和“结束”之间是否已经抛出异常,因此无法相应地处理“结束”部分。
这两个问题使得使用这种结构不切实际,这是一个非常令人沮丧的事实。
现在,我的问题是:
我对这些问题的理解正确吗?这就是“using”实际上的工作方式吗?
如果是这样,除了释放资源和清理外,“using”结构是否有其他方法可以克服这些问题并发挥实际作用?
如果“using”无法以这种方式实际使用,那么替代方法是什么(强制执行具有起始和结束部分的代码上下文)?