对于 C# 中的不同异常类型,使用带有类型检查的单个 catch 块与使用多个 catch 块有何含义?
在 C# 中,处理异常时,可以使用带有类型检查的单个 catch 块:
try
{
// ...
}
catch(Exception ex)
{
if (ex is ObjectNotFoundException)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
else if (ex is ModelValidationException)
{
return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, ex);
}
//... another type of exception
else {
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
}
}
或者,可以为每种异常类型使用单独的 catch 块:
try
{
// ...
}
catch (ObjectNotFoundException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
catch (ModelValidationException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, ex);
}
//... another type of exception
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
}
每种方法的优点和潜在缺陷是什么?是否有任何性能考虑因素或最佳实践需要考虑?
第二种方法更好,因为您不想默默地吞下所有其他异常。但是,与其让进程在获取未捕获的异常类型后崩溃,不如捕获它们,记录错误详细信息并返回内部服务器错误:
try
{
// ...
}
catch (ObjectNotFoundException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
catch (ModelValidationException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, ex);
}
catch(Exception ex)
{
// log this error, so you are notified about it
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
}
第二种方法是正确的,捕获特定的异常类型。
第一种方法,
try
{
...
}
catch(Exception ex)
{
if (ex is ObjectNotFoundException)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
if (ex is ModelValidationException)
{
return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, ex);
}
}
是个坏主意,不要这样做!它抑制并丢弃意外的异常。
如果异常与您的 if 条件之一不匹配,则不会重新抛出异常。你可以通过这样做从根本上改善事情,
try
{
...
}
catch(Exception ex)
{
...
throw;
}
但是,如果您想要一个捕获特定类型的 catch 块,请使用常规模式。这在未来更有可能被理解和支持,并且不太可能导致意外的错误。
此外,我怀疑类型化捕获将具有性能优势,因为内置类型检查可能已得到优化。
但是,您需要使用定义的工作负载运行基准测试来验证该假设。