19

私のコードでは、aSystem.Reflection.TargetInvocationExceptionがスローされる状況に遭遇しています。ある特定のケースでは、ルート例外を処理する方法を知っていますが、他のすべての例外をスローしたいと思います。これを行うには2つの方法が考えられますが、どちらが良いかわかりません。

1.1。

try
{
    //code
}
catch (System.Reflection.TargetInvocationException ex)
{
    if (typeof(ex.InnerException) == typeof(SpecificException))
    {
        //fix
    }
    else
    {
        throw ex.Innerexception;
    }
}

2.2。

try
{
    //code
}
catch (System.Reflection.TargetInvocationException ex)
{
    try
    {
        throw ex.InnerException;
    }
    catch (SpecificException exSpecific)
    {
        //fix
    }
}

一般的に例外のスローは遅いことを知っているので、最初の方法の方がおそらく速いと思います。あるいは、私が考えていなかったこれを行うためのより良い方法はありますか?

4

3 に答える 3

37

提案されたソリューションにはそれぞれ独自の問題があります。

最初のメソッドは、内部例外のタイプが期待どおりのタイプであることを確認します。これは、派生型が一致しないことを意味します。これは、意図したものではない可能性があります。

2番目のメソッドは、Dan Puzeyが述べたように、内部例外のスタックトレースを現在のスタック位置で上書きします。スタックトレースを破棄すると、バグを修正するために必要な1つのリードが破棄される可能性があります。

解決策は基本的に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.
    } 
}

処理できないことが判明した例外を再スローする場合はthrow ex;、スタックトレースが上書きされるため、実行しないでください。代わりにthrow;、スタックトレースを保持するwhichを使用してください。それは基本的に「私は実際にこの条項を入力したくなかっ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
}
于 2012-04-12T09:20:22.363 に答える
1

あなたの#2は間違いなく興味深い解決策です!

ただし、注意が必要です。通常、最初にキャッチTargetInvocationExceptionされたときに別のコンポーネントによってスローされます。別の場所から再スローするため、スタックトレースなどの情報を破棄する場合。 InnerExceptionthrow ex.InnerException

ですから、あなたが提案した2つのうち、私は間違いなく#1を選ぶことをお勧めします。私はあなたが持っている構造内の代替案を知りません。ただし、InnerExceptionは元々他の場所でスローされます。例外がスローされる場所の近くに、この失敗を処理するためのよりエレガントな場所があるかどうかを調査する価値があります。

于 2012-04-12T09:12:46.097 に答える
-2
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; 
    } 
} 
于 2012-04-12T09:09:23.570 に答える