C# 在使用 throw 后没有进入异常

C# not entering exception after using throw

我是一名初级程序员,最近遇到了异常。我在下面做了这个小测试,我收到的输出与我预期的不一样。

static void Main(string[] args)
    {
        ushort var = 65535;
        try
        {
            checked { var++; }
        }
        catch (OverflowException)
        {
            Console.WriteLine("Hello!");
            throw;
        }
        catch
        {
            Console.WriteLine("Here I am!");

        }
    }

我希望程序执行以下操作:

然而,我只进入了屏幕"Hello!"。

编辑:感谢那些发表评论的人。我想我开始明白了。然而,我的困惑源于我正在阅读的这本书:C# 4.0.

我可以显示文本,但它是葡萄牙语。我要翻译一下它说的:"Sometimes it is useful to propagate the exception through more than one catch. For example, let's suposse it is necessary to show a specific error message due to the fact that the "idade" is invalid,但我们仍然需要关闭程序,作为global catch中的那部分。在这种情况下,有必要在之后传播异常执行第一个 catch 块。为此,您只需执行一个不带参数的简单 throw。"

Example from the book

在本书的这个例子中,您可以看到程序员在做与我相同的事情。至少它看起来像。我错过了什么吗?还是书错了?

希望你能帮助我。谢谢!

我经常 link 有两篇关于异常处理的文章。我个人认为他们在与他们打交道时需要阅读:

https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/

https://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET

对于这种情况,您没有抛出异常。你是重新投掷你抓到的。把它想象成一个渔夫在做 "catch and release"。它可以用于某些场景,比如这次我为卡在 .NET 1.1 上的人写了一个 TryParse 替代品:

//Parse throws ArgumentNull, Format and Overflow Exceptions.
//And they only have Exception as base class in common, but identical handling code (output = 0 and return false).

bool TryParse(string input, out int output){
  try{
    output = int.Parse(input);
  }
  catch (Exception ex){
    if(ex is ArgumentNullException ||
      ex is FormatException ||
      ex is OverflowException){
      //these are the exceptions I am looking for. I will do my thing.
      output = 0;
      return false;
    }
    else{
      //Not the exceptions I expect. Best to just let them go on their way.
      throw;
    }
  }

  //I am pretty sure the Exception replaces the return value in exception case. 
  //So this one will only be returned without any Exceptions, expected or unexpected
  return true;

}

但根据经验,您应该使用 "finally" 块之类的东西来进行清理工作,而不是捕获并释放。 throw inside a catch block 是你很少使用的东西。

总之,你做错了。让我们访问文档

Exception Handling (C# Programming Guide)

Multiple catch blocks with different exception filters can be chained together. The catch blocks are evaluated from top to bottom in your code, but only one catch block is executed for each exception that is thrown.

虽然它没有明确说明您不能捕获在异常过滤器中重新抛出的异常,但事实是您不能。这将是一场噩梦,并且会产生复杂且意想不到的结果。

也就是说,您将需要 try catch 的另一层(内部或外部)来捕获 catch (OverflowException)

中抛出的异常

如果嵌套 try/catch 个块,您将获得预期的输出:

static void Main(string[] args)
{
    try
    {
        ushort var = 65535;
        try
        {
            checked { var++; }
        }
        catch (OverflowException)
        {
            Console.WriteLine("Hello!");
            throw;
        }
    }
    catch
    {
        Console.WriteLine("Here I am!");
    }
}