使用throw后C#没有输入异常

问题描述 投票:0回答:3

我是一名初学程序员,最近我遇到过例外情况。我在下面做了这个小测试,我收到的输出与我预期的输出不一样。

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

        }
    }

我期待该程序执行以下操作:

  • 尝试var ++,失败并创建一个OverflowException;
  • 输入Catch(OverflowException)并写入“Hello!”;
  • 抛出异常并输入catch;
  • 写下“我在这里!”。

但是,我只在屏幕上显示“你好!”。

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

我可以显示文字,但它是葡萄牙语。我将翻译它所说的内容:“有时通过多个catch来传播异常是有用的。例如,我们认为有必要显示一条特定的错误消息,因为”idade“无效,但是我们仍然需要关闭程序,作为全局catch中的那一部分。在这种情况下,有必要在执行第一个catch块之后传播异常。为此,你只需要做一个简单的throw没有争论。“

Example from the book

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

希望您能够帮助我。谢谢!

c# exception try-catch throw
3个回答
0
投票

如果嵌套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!");
    }
}

1
投票

简而言之,你做错了。让我们访问文档

Exception Handling (C# Programming Guide)

具有不同异常过滤器的多个catch块可以链接在一起。 catch块在代码中从上到下进行计算,但是对于抛出的每个异常只执行一个catch块。

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

这就是说,你需要try catch的另一层(内部或外部)来捕获catch (OverflowException)中抛出的异常


0
投票

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

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

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

至于这种情况,你不会抛出异常。你重新扔了一个你抓到的。可以把它想象成一个“抓住并释放”的渔夫。它可以用于某些场景,比如这次我为一个卡在.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”块这样的东西进行清理工作,而不是捕获和释放。扔进一个catch区块是你很少使用的东西。

© www.soinside.com 2019 - 2024. All rights reserved.