首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当ctor和finalizer都抛出异常时,如何处理C#类中的所有异常?

当ctor和finalizer都抛出异常时,如何处理C#类中的所有异常?
EN

Stack Overflow用户
提问于 2010-04-20 09:17:40
回答 3查看 451关注 0票数 2

在某些情况下,如何处理类似以下类的所有异常?

代码语言:javascript
复制
class Test : IDisposable {
  public Test() {
    throw new Exception("Exception in ctor");  
  }
  public void Dispose() {
    throw new Exception("Exception in Dispose()");
  }
  ~Test() {
    this.Dispose();
  }
}

我试过了,但不起作用:

代码语言:javascript
复制
static void Main() {
  Test t = null;
  try {
    t = new Test();
  }
  catch (Exception ex) {
    Console.Error.WriteLine(ex.Message);
  }

  // t is still null
}

我也尝试使用"using“,但它不能处理~Test()抛出的异常;

代码语言:javascript
复制
static void Main() {
  try {
    using (Test t = new Test()) { }
  }
  catch (Exception ex) {
    Console.Error.WriteLine(ex.Message);
  }
}

有什么想法吗?我该怎么做?

EN

回答 3

Stack Overflow用户

发布于 2010-04-20 09:24:13

首先,终结器应该永远不会抛出异常()。如果是这样的话,一定是出了灾难性的问题,应用程序应该会严重崩溃。终结器也不应该直接调用Dispose()。终结器仅用于释放非托管资源,因为一旦终结器运行,托管资源甚至可能不处于有效状态。托管引用已经被垃圾回收器清除,因此您只需要在Dispose中处理它们,而不是在Finalizer中。

也就是说,如果显式调用Dispose,则应捕获Dispose中的异常。我不能很好地理解“使用”的情况是如何没有抛出异常的。也就是说,如果你能避免的话,Dispose也不应该抛出异常。特别是,在using块之后抛出异常的Dispose将用Dispose异常“覆盖”using块内可能发生的任何异常。

一些额外的参考材料here

票数 5
EN

Stack Overflow用户

发布于 2010-04-20 09:30:29

我认为部分答案是你不应该在这些情况下处理异常。

只有在可以从异常中恢复,或者可以向异常添加附加信息并重新引发时,才应该捕获异常。您不应该捕获每个异常。让调用堆栈中较高层的代码处理尽可能多的异常。

票数 3
EN

Stack Overflow用户

发布于 2010-04-20 10:35:02

我有几点看法。

首先,避免从Dispose抛出异常。事实上,我几乎可以说永远不会。.NET开发人员已经习惯于期望Dispose总是成功,这是有充分理由的。每次都将调用包装在try-catch中会很笨拙,而且肯定会降低可读性。

其次,这是一个经常争论的问题,避免从构造函数中抛出异常。但是,像SqlException这样不可预测的异常会迫使调用者将构造函数包装在try-catch块中。再一次,这导致了笨拙的编码场景。没有实例引用,调用方无法调用Dispose。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2671948

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档