我们正在研究C#中的编码模式,我们希望在其中使用带有特殊类的"using"子句,Dispose()根据"using"主体是正常退出还是异常退出,其方法会有不同的含义.
据我所知,CLR会跟踪当前正在处理的异常,直到它被"catch"处理程序占用为止.但是,这些信息是否以任何方式公开以供代码访问并不完全清楚.你知道它是否,如果是,如何访问它?
例如:
using (var x = new MyObject())
{
x.DoSomething();
x.DoMoreThings();
}
class MyObject : IDisposable
{
public void Dispose()
{
if (ExceptionIsBeingHandled)
Rollback();
else
Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
这几乎看起来像System.Transactions.TransactionScope,除了成功/失败不是通过调用确定x.Complete(),而是基于using身体是否正常退出.
对于需要开始和分离结束部分的情况," 使用 "构造看起来非常方便.
快速举例说明:
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 + ">")
}
}
Run Code Online (Sandbox Code Playgroud)
开头部分定义为构造函数,结束部分是Dispose方法.
然而,尽管有吸引力,但这个结构有一个严重的警告,这个警告来自Dispose方法是从finally块中调用的.所以有两个问题:
您应该避免从finally块中抛出异常,因为它们将覆盖应该捕获的原始异常.
如果在"开始"和"结束"之间抛出异常,则无法知道Dispose方法的内部,因此无法相应地处理"结束"部分.
这两件事使得使用这种结构变得不切实际,这是一个非常可悲的事实.现在,我的问题是:
我对问题的理解是对的吗?这是"使用"实际上如何工作?
如果是这样,有没有办法克服这些问题,并实际使用"使用"结构,而不是它最初的设计(释放资源和清理)
如果没有实用的方法来"使用"这种方式.有哪些替代方法(使用开头和结尾部分强制执行某些代码的上下文)?
c# language-features design-patterns exception-handling exception