【问题标题】:Can I not catch a specific or custom exception?我不能捕获特定或自定义异常吗?
【发布时间】:2012-09-06 13:44:46
【问题描述】:

我不想捕获一些异常。我能做到吗?

我可以这样说吗:

catch (Exception e BUT not CustomExceptionA)
{
}

?

【问题讨论】:

标签: c# .net exception-handling


【解决方案1】:
try
{
      // Explosive code
}
catch (CustomExceptionA){ throw; }
catch (Exception ex)
{
    //classic error handling
}

【讨论】:

  • 你的解决方案比我的好,我必须说!
【解决方案2】:
try
{
}
catch (Exception ex)
{
    if (ex is CustomExceptionA)
    {
        throw;
    }
    else
    {
        // handle
    }
}

【讨论】:

    【解决方案3】:

    从 C# 6 开始,您可以使用 exception filter:

    try
    {
        // Do work
    }
    catch (Exception e) when (!(e is CustomExceptionA))
    {
        // Catch anything but CustomExceptionA
    }
    

    【讨论】:

    • 谢谢。这显然是最好的方法。它不会像 throw; 那样破坏原始堆栈。
    【解决方案4】:

    你可以过滤它:

    if (e is CustomExceptionA) throw;
    

    当然,你可以抓住它并重新抛出它:

    try
    {
    }
    catch (CustomExceptionA) { throw; }
    catch (Exception ex) { ... }
    

    【讨论】:

    • throw 而不是 throw e 将使堆栈跟踪大部分保持完好。
    • @DanielHilgarth 对,改了。但这取决于你想要什么恕我直言。
    【解决方案5】:

    首先,除非您记录并重新抛出异常,否则捕获异常是不好的做法。但如果必须,您需要捕获自定义异常并像这样重新抛出它:

    try
    {
    }
    catch (CustomExceptionA custome)
    {
        throw custome;
    }
    catch (Exception e)
    {
        // Do something that hopefully re-throw's e
    }
    

    【讨论】:

      【解决方案6】:

      在 cmets 中接受 @Servy 的教育后,我想到了一个解决方案,可以让你做 [我认为的] 你想做的事情。让我们创建一个方法IgnoreExceptionsFor(),如下所示:

      public void PreventExceptionsFor(Action actionToRun())
      {
          try
          {
               actionToRun();
          }
          catch
          {}
      }
      

      然后可以这样调用:

      try
      {
           //lots of other stuff
           PreventExceptionsFor(() => MethodThatCausesTheExceptionYouWantToIgnore());
           //other stuff
      }
      catch(Exception e)
      {
          //do whatever
      }
      

      这样,除了PreventExceptionsFor() 的那一行之外的每一行都会正常抛出异常,而PreventExceptionsFor() 里面的那一行会被悄悄地通过。

      【讨论】:

      • @Servy 在我看来,OP 希望忽略某些异常并处理其他异常,代码在被忽略的异常之后继续运行。其他几个人发布了将异常提升到更高级别的方法,但没有一个实现该功能。如果 OP 想知道如何将异常重新抛出到更高的级别,那么他似乎会这样问。请注意,try 中的代码在异常被重新抛出后将不会继续。
      • OP 要求一种方法来不捕获某种类型的异常。不捕获它的效果是异常被重新抛出,直到它遇到另一个 try/catch 块,而不是它在抛出异常的地方继续执行。他并没有问如何首先防止抛出异常。虽然从技术上讲,提供的解决方案确实捕获了自定义异常,但效果是该异常似乎从未被捕获,因为它被重新抛出。
      • @Servy 任何人想要重新抛出异常的唯一合乎逻辑的原因是在别处捕获它。如果他想在其他地方捕获它,他不会问如何不捕获异常。我的猜测是他有一个他希望被抛出的异常,但被抛出的异常并不一定会导致任何问题。也许像var a Session["whatever"]; if(a==null) a=default(A); 这样的东西如果 Session 抛出一个 nullref 或其他东西,谁在乎,我们仍然希望获得默认值。我的答案是唯一允许这样做的。
      • the only logical reason anyone would want to rethrow an exception is to catch it elsewhere 那,或者这是一个致命的异常,应该让应用程序崩溃。请注意,他没有说过任何暗示想要你所要求的行为。如果那是他想要的,那么他需要提出要求。此外,您的答案不涉及不引发异常,这似乎是您认为 OP 想要的。您的回答基本上是,“明确捕获除扩展Exception 的自定义异常之外的所有异常”。这不是一个特别实用的选择。
      • @Servy 鉴于问题是“如何捕获除特定异常之外的所有异常?”,我会说“捕获除自定义异常之外的所有异常”实际上看起来很不错-在回答,不是吗?通过假设他正在处理一个致命的异常,你和我一样猜测。那么谁的答案更正确呢?我不知道,这取决于OP实际想要什么。不过,我的回答确实带来了不鼓励不良编码实践的好处。异常应该(几乎)永远不会被重新抛出。最好让它们冒泡到可以处理的地方。
      猜你喜欢
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      • 2014-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      相关资源
      最近更新 更多