C# 检查内部异常的类型
在我的代码中,我遇到了这样一种情况:抛出了C# 检查内部异常的类型,c#,C#,在我的代码中,我遇到了这样一种情况:抛出了System.Reflection.targetingException。在一个特定情况下,我知道如何处理根异常,但我想抛出所有其他异常。我可以想出两种方法,但我不确定哪种更好 一, 二, 我知道抛出异常通常很慢,所以我觉得第一种方法可能会更快。或者,有没有更好的方法来实现这一点,我还没有想到 try { //code } catch (System.Reflection.TargetInvocationException ex) {
System.Reflection.targetingException
。在一个特定情况下,我知道如何处理根异常,但我想抛出所有其他异常。我可以想出两种方法,但我不确定哪种更好
一,
二,
我知道抛出异常通常很慢,所以我觉得第一种方法可能会更快。或者,有没有更好的方法来实现这一点,我还没有想到
try
{
//code
}
catch (System.Reflection.TargetInvocationException ex)
{
if (ex.InnerException is SpecificException)
{
//fix
}
else
{
throw ex.InnerException;
}
}
或
或
你的#2绝对是一个有趣的解决方案
不过,您确实需要小心:TargetInvocationException
通常会在另一个组件首次捕获InnerException
时被另一个组件抛出。如果你抛出ex.InnerException
你会破坏它包含的一些信息(比如堆栈跟踪),因为你是从不同的位置抛出它的
所以在你提出的两个建议中,我绝对建议你选择1。我不知道在你现有的结构中还有其他选择。然而,InnerException最初是在其他地方抛出的——值得研究的是,是否有一个更优雅的地方来处理此故障,离抛出异常的地方更近。您提出的每个解决方案都有自己的问题 第一个方法检查内部异常的类型是否正是您期望的类型。这意味着派生类型将不匹配,这可能不是您想要的 第二种方法用当前堆栈位置覆盖内部异常的堆栈跟踪,如Dan Puzey所述。销毁堆栈跟踪可能就是销毁修复bug所需的一条线索 解决方案基本上是DarkGray发布的,有Nick的建议,还有我自己的建议(在
else
中):
如果你想重新抛出一个你无法处理的异常,不要抛出ex代码>因为这将覆盖堆栈跟踪。使用throw代码>保留堆栈跟踪。它的基本意思是“我实际上不想输入这个catch
子句,假装我从未捕获异常”
更新:C#6.0通过异常过滤器提供了更好的语法:
2很吸引人,imho 1更具可读性,从性能角度来看可能更好。问题:引发TargetInvocationException
的调用是什么?是您的代码,还是第三方?它是从数据库读取的生成代码。为什么不使用Is
关键字?您的代码在功能上与最初的建议没有什么不同,您也没有为代码提供任何推理或理由。+1指出抛出之间的区别代码>和抛出ex代码>
try
{
//code
}
catch (System.Reflection.TargetInvocationException ex)
{
try
{
throw ex.InnerException;
}
catch (SpecificException exSpecific)
{
//fix
}
}
try
{
//code
}
catch (System.Reflection.TargetInvocationException ex)
{
if (ex.InnerException is SpecificException)
{
//fix
}
else
{
throw ex.InnerException;
}
}
try
{
//code
}
catch (System.Reflection.TargetInvocationException ex)
{
SpecificException spExc = ex.InnerException as SpecificException;
if (spExc != null)
{
bla-bla spExc
}
else
{
throw ex.InnerException;
}
}
try
{
//code
}
catch (System.Reflection.TargetInvocationException ex)
{
if (ex.InnerException.GetType() == typeof(SpecificException))
{
//fix
}
else
{
throw ex.InnerException;
}
}
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.
}
}
try
{
// Do something
}
catch (TargetInvocationException ex) when (ex.InnerException is SpecificException)
{
// Handle SpecificException
}
catch (TargetInvocationException ex) when (ex.InnerException is SomeOtherSpecificException)
{
// Handle SomeOtherSpecificException
}