哪种方法(为了性能)确定异常类型更好?
Which is the better way (for performance) to determine the exception type?
我已经从 ExceptionFilterAttribute
覆盖了 OnException
。
public override void OnException(HttpActionExecutedContext context) {
base.OnException(context);
}
当抛出错误并将异常作为参数传递时调用此函数:- context.Exception
确定错误类型的最佳性能方法是:
1).投掷和接球
//create a new response that will be sent to the API consumer
var response = new System.Net.Http.HttpResponseMessage();
//throw the error that came through to catch it specifically
try {
throw context.Exception;
}
catch (System.IO.FileNotFoundException) {
response.StatusCode = HttpStatusCode.NotFound;
}
catch (Exception) {
response.StatusCode = HttpStatusCode.InternalServerError;
}
2).获取类型
//create a new response that will be sent to the API consumer
var response = new System.Net.Http.HttpResponseMessage();
//switch on the exception type
if (context.Exception.GetType() == typeof(System.IO.FileNotFoundException)) {
response.StatusCode = HttpStatusCode.NotFound;
}
else if (context.Exception.GetType() == typeof(Exception)) {
response.StatusCode = HttpStatusCode.InternalServerError;
}
3). 其他方式?
我怀疑(尽管尚未证实)第一种方法会破坏堆栈跟踪数据,或者以其他方式修改异常本身并丢失原始信息。即使碰巧它没有这样做,但出于性能和语义原因,它仍然不是很好。 throw
ing 很昂贵,调试时异常的来源变得稍微难以确定,并且它打破了从不使用异常进行逻辑流程的标准规则。
第二种方式的结构比较好,但是实现上还有待改进。像这样:
var response = new System.Net.Http.HttpResponseMessage();
if (context.Exception is System.IO.FileNotFoundException) {
response.StatusCode = HttpStatusCode.NotFound;
}
else {
response.StatusCode = HttpStatusCode.InternalServerError;
}
更新: 评论是正确的,对 Exception
类型的任何其他异常的运行时检查都会成功,因此不需要检查。只需检查特定的异常类型,然后默认为任何其他类型。
这真的取决于你想要实现什么,但我绝对不会为了确定类型而抛出和捕获异常。除了第二种方法,您可能还想考虑使用 is
运算符。这将更像抛出和捕获,因为它检查对象是否可以转换为类型,而 GetType
将获得异常的确切类型。
var response = new System.Net.Http.HttpResponseMessage();
if (context.Exception is System.IO.FileNotFoundException)
{
response.StatusCode = HttpStatusCode.NotFound;
}
else if (context.Exception is IOException)
{
response.StatusCode = HttpStatusCode.InternalServerError;
}
在上面的示例中,第一个 if 仅适用于 FileNotFoundException
,第二个适用于属于或继承自 IOException
的任何其他异常。
三个。
抛出异常以捕获它意味着创建了一个全新的异常对象,因此这比需要的工作多得多。
第二种方法更好,但还可以改进。
您可以使用 is
运算符来检查对象的类型:
if (context.Exception is System.IO.FileNotFoundException)) {
response.StatusCode = HttpStatusCode.NotFound;
} else if (context.Exception is Exception) {
response.StatusCode = HttpStatusCode.InternalServerError;
}
您可以获得 class 的名称并在开关中使用:
switch (context.Exception.GetType().FullName) {
case "System.IO.FileNotFoundException":
response.StatusCode = HttpStatusCode.NotFound;
break;
case "Exception":
response.StatusCode = HttpStatusCode.InternalServerError;
break;
}
注意,不同的方法匹配的内容是有区别的。 is
运算符还将包括基类型(就像 catch(Exception)
一样),因此 context.Exception is Exception
对所有异常都为真。 switch 只会进行精确匹配,就像 context.Exception.GetType() == typeof(Exception)
.
我已经从 ExceptionFilterAttribute
覆盖了 OnException
。
public override void OnException(HttpActionExecutedContext context) {
base.OnException(context);
}
当抛出错误并将异常作为参数传递时调用此函数:- context.Exception
确定错误类型的最佳性能方法是:
1).投掷和接球
//create a new response that will be sent to the API consumer
var response = new System.Net.Http.HttpResponseMessage();
//throw the error that came through to catch it specifically
try {
throw context.Exception;
}
catch (System.IO.FileNotFoundException) {
response.StatusCode = HttpStatusCode.NotFound;
}
catch (Exception) {
response.StatusCode = HttpStatusCode.InternalServerError;
}
2).获取类型
//create a new response that will be sent to the API consumer
var response = new System.Net.Http.HttpResponseMessage();
//switch on the exception type
if (context.Exception.GetType() == typeof(System.IO.FileNotFoundException)) {
response.StatusCode = HttpStatusCode.NotFound;
}
else if (context.Exception.GetType() == typeof(Exception)) {
response.StatusCode = HttpStatusCode.InternalServerError;
}
3). 其他方式?
我怀疑(尽管尚未证实)第一种方法会破坏堆栈跟踪数据,或者以其他方式修改异常本身并丢失原始信息。即使碰巧它没有这样做,但出于性能和语义原因,它仍然不是很好。 throw
ing 很昂贵,调试时异常的来源变得稍微难以确定,并且它打破了从不使用异常进行逻辑流程的标准规则。
第二种方式的结构比较好,但是实现上还有待改进。像这样:
var response = new System.Net.Http.HttpResponseMessage();
if (context.Exception is System.IO.FileNotFoundException) {
response.StatusCode = HttpStatusCode.NotFound;
}
else {
response.StatusCode = HttpStatusCode.InternalServerError;
}
更新: 评论是正确的,对 Exception
类型的任何其他异常的运行时检查都会成功,因此不需要检查。只需检查特定的异常类型,然后默认为任何其他类型。
这真的取决于你想要实现什么,但我绝对不会为了确定类型而抛出和捕获异常。除了第二种方法,您可能还想考虑使用 is
运算符。这将更像抛出和捕获,因为它检查对象是否可以转换为类型,而 GetType
将获得异常的确切类型。
var response = new System.Net.Http.HttpResponseMessage();
if (context.Exception is System.IO.FileNotFoundException)
{
response.StatusCode = HttpStatusCode.NotFound;
}
else if (context.Exception is IOException)
{
response.StatusCode = HttpStatusCode.InternalServerError;
}
在上面的示例中,第一个 if 仅适用于 FileNotFoundException
,第二个适用于属于或继承自 IOException
的任何其他异常。
三个。
抛出异常以捕获它意味着创建了一个全新的异常对象,因此这比需要的工作多得多。
第二种方法更好,但还可以改进。
您可以使用 is
运算符来检查对象的类型:
if (context.Exception is System.IO.FileNotFoundException)) {
response.StatusCode = HttpStatusCode.NotFound;
} else if (context.Exception is Exception) {
response.StatusCode = HttpStatusCode.InternalServerError;
}
您可以获得 class 的名称并在开关中使用:
switch (context.Exception.GetType().FullName) {
case "System.IO.FileNotFoundException":
response.StatusCode = HttpStatusCode.NotFound;
break;
case "Exception":
response.StatusCode = HttpStatusCode.InternalServerError;
break;
}
注意,不同的方法匹配的内容是有区别的。 is
运算符还将包括基类型(就像 catch(Exception)
一样),因此 context.Exception is Exception
对所有异常都为真。 switch 只会进行精确匹配,就像 context.Exception.GetType() == typeof(Exception)
.