Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查内部异常的类型_C# - Fatal编程技术网

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
}