我是一名初学程序员,最近我遇到过例外情况。我在下面做了这个小测试,我收到的输出与我预期的输出不一样。
static void Main(string[] args)
{
ushort var = 65535;
try
{
checked { var++; }
}
catch (OverflowException)
{
Console.WriteLine("Hello!");
throw;
}
catch
{
Console.WriteLine("Here I am!");
}
}
我期待该程序执行以下操作:
但是,我只在屏幕上显示“你好!”。
编辑:感谢评论的人。我想我已经开始明白了。然而,我的困惑源于我正在读的这本书:C#4.0。
我可以显示文字,但它是葡萄牙语。我将翻译它所说的内容:“有时通过多个catch来传播异常是有用的。例如,我们认为有必要显示一条特定的错误消息,因为”idade“无效,但是我们仍然需要关闭程序,作为全局catch中的那一部分。在这种情况下,有必要在执行第一个catch块之后传播异常。为此,你只需要做一个简单的throw没有争论。“
在本书的这个例子中,你可以看到程序员做了同样的事情。至少它看起来像。我错过了什么吗?或者这本书错了吗?
希望您能够帮助我。谢谢!
如果嵌套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!");
}
}
简而言之,你做错了。让我们访问文档
Exception Handling (C# Programming Guide)
具有不同异常过滤器的多个catch块可以链接在一起。 catch块在代码中从上到下进行计算,但是对于抛出的每个异常只执行一个catch块。
虽然没有具体说你不能捕获异常过滤器中重新抛出的异常,但事实是你不能。这将是一场噩梦,并且会产生复杂而意想不到的结果
这就是说,你需要try catch
的另一层(内部或外部)来捕获catch (OverflowException)
中抛出的异常
我经常链接两篇关于异常处理的文章。我个人认为他们在与他们打交道时需要阅读:
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区块是你很少使用的东西。