[C#技巧]C#异常when过滤器捕捉异常使用多个catch的示例代码
作者:admin 时间:2023-5-6 11:21:52 浏览:你的代码中是否存在需要多次处理特定异常的情况?我们经常会遇到这样的情况,我们必须根据某种条件执行不同的异常处理逻辑。
假设我们想在捕捉异常HttpRequestException
时,StatusCode=400(Bad Request)时以一种方式处理,而StatusCode=404 (Not Found)时以另一种方式处理,你可能想到编写一个 if
语句来检查条件:
try
{
await GetBlogsFromApi();
}
catch (HttpRequestException e)
{
if (e.StatusCode == HttpStatusCode.BadRequest)
{
HandleBadRequest(e);
}
else if (e.StatusCode == HttpStatusCode.NotFound)
{
HandleNotFound(e);
}
}
虽然这可行,但它不是最干净的方法,有一个你可能不知道的更好的解决方案。
实际上,try-catch
可以使用多个catch
字句,发生异常时,按指定顺序从上到下检查 catch
子句。但是,对于任何抛出的异常,最多只catch
执行一个块。如前例所示,你可以省略异常变量的声明并在 catch
子句中仅指定异常类型。没有任何指定异常类型的 catch
子句匹配任何异常,如果存在,则必须是最后一个 catch
子句。
以下是我们如何根据特定条件优雅地捕获相同的异常:
try
{
await GetBlogsFromApi();
}
catch (HttpRequestException e) when (e.StatusCode == HttpStatusCode.BadRequest)
{
HandleBadRequest(e);
}
catch (HttpRequestException e) when (e.StatusCode == HttpStatusCode.NotFound)
{
HandleNotFound(e);
}
这个就是异常when过滤器,使用异常过滤器来提供单个catch
块来处理两种指定类型的异常。
如果它们通过异常过滤器区分catch
,你可以为相同的异常类型提供多个子句,其中一个子句可能没有异常过滤器。如果存在这样的子句,它必须是指定该异常类型的子句的最后一个。除了异常类型,你可以指定一个异常过滤器,进一步检查异常并决定相应的catch
块是否处理该异常。
异常过滤器是关键字后面的布尔表达式when
,当我们需要添加更多条件时,这种方法更简洁、更容易扩展。
如果要重新抛出捕获的异常,请使用throw
语句,如以下示例所示:
try
{
var result = Process(-3, 4);
Console.WriteLine($"Processing succeeded: {result}");
}
catch (Exception e)
{
LogError(e, "Processing failed.");
throw;
}
注意throw;
保留异常的原始堆栈跟踪,它存储在Exception.StackTrace
属性中,与此相反,throw e;
更新 的StackTrace属性e
。 参考文章:
[C#技巧]C#重新抛出异常的正确方法,注意不是throw e!
相关文章
- 站长推荐