1. ホーム
  2. c#

[解決済み] C#でスタックトレースを失うことなくInnerExceptionを再スローする方法は?

2022-03-16 11:42:44

質問

リフレクションを通して、例外を引き起こす可能性のあるメソッドを呼び出しています。リフレクションが周りに置くラッパーなしで、どのように私の呼び出し側に例外を渡すことができますか?
InnerExceptionを再スローしていますが、これではスタックトレースが破壊されてしまいます。
コード例です。

public void test1()
{
    // Throw an exception for testing purposes
    throw new ArgumentException("test1");
}

void test2()
{
    try
    {
        MethodInfo mi = typeof(Program).GetMethod("test1");
        mi.Invoke(this, null);
    }
    catch (TargetInvocationException tiex)
    {
        // Throw the new exception
        throw tiex.InnerException;
    }
}

解決方法は?

.NET 4.5 は、現在では ExceptionDispatchInfo クラスがあります。

これにより、スタックトレースを変更することなく、例外を捕捉して再スローすることができます。

using ExceptionDispatchInfo = 
    System.Runtime.ExceptionServices.ExceptionDispatchInfo;

try
{
    task.Wait();
}
catch(AggregateException ex)
{
    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}

に限らず、あらゆる例外に対して機能します。 AggregateException .

により導入されました。 await C#言語の機能で、内側の例外をアンラップして AggregateException インスタンスを作成し、非同期言語機能をより同期言語機能に近づけることを目的としています。