在我的代码中,我遇到了System.Reflection.TargetInvocationException抛出a的情况.在一个特定的情况下,我知道我想如何处理根异常,但我想抛出所有其他异常.我可以想到两种方法,但我不确定哪种方式更好.
1.
try
{
//code
}
catch (System.Reflection.TargetInvocationException ex)
{
if (typeof(ex.InnerException) == typeof(SpecificException))
{
//fix
}
else
{
throw ex.Innerexception;
}
}
Run Code Online (Sandbox Code Playgroud)
2.
try
{
//code
}
catch (System.Reflection.TargetInvocationException ex)
{
try
{
throw ex.InnerException;
}
catch (SpecificException exSpecific)
{
//fix
}
}
Run Code Online (Sandbox Code Playgroud)
我知道抛出异常通常很慢,所以我觉得第一种方法可能会更快.或者,有没有更好的方法来做到这一点,我没有想到?
All*_*nek 28
您提出的每个解决方案都有自己的问题.
第一种方法检查内部异常的类型是否与您期望的类型完全相同.这意味着派生类型将不匹配,这可能不是您想要的.
Dan Puzey提到,第二种方法用当前堆栈位置覆盖内部异常的堆栈跟踪.销毁堆栈跟踪可能会破坏您需要的一个引导来修复错误.
解决方案基本上就是DarkGray发布的内容,以及Nick的建议以及我自己(在else)的附加建议:
try
{
// Do something
}
catch (TargetInvocationException ex)
{
if (ex.InnerException is SpecificException)
{
// Handle SpecificException
}
else if (ex.InnerException is SomeOtherSpecificException)
{
// Handle SomeOtherSpecificException
}
else
{
throw; // Always rethrow exceptions you don't know how to handle.
}
}
Run Code Online (Sandbox Code Playgroud)
如果你想重新抛出一个你无法处理的异常,那就不要throw ex;因为那将覆盖堆栈跟踪.而是使用throw;它来保留堆栈跟踪.它基本上意味着"我实际上不想进入这个catch条款,假装我从来没有发现异常".
更新: C#6.0通过异常过滤器提供了更好的语法:
try
{
// Do something
}
catch (TargetInvocationException ex) when (ex.InnerException is SpecificException)
{
// Handle SpecificException
}
catch (TargetInvocationException ex) when (ex.InnerException is SomeOtherSpecificException)
{
// Handle SomeOtherSpecificException
}
Run Code Online (Sandbox Code Playgroud)