オブジェクトを動的に呼び出し、MethodInfo
その内部からスローされた例外を、通常どおり呼び出されたかのように外側に渡したいと考えています。
2つのオプションがあるようです。それらの概要を以下に示します。
オプション 1は によってスローされた例外のタイプを維持しますMyStaticFunction
が、StackTrace
が原因で が台無しになりthrow
ます。
オプション 2は例外の を維持しStackTrace
ますが、例外のタイプは常にTargetInvocationException
です。InnerException
とその型を引き出すことはできますが、たとえば次のように書くことはできません。
try { DoDynamicCall(); }
catch (MySpecialException e) { /* special handling */ }
オプション1:
void DoDynamicCall()
{
MethodInfo method = /*referencing MyClass method void MyStaticFunction(int x)*/;
try
{
method.Invoke(null, new object[] { 5 });
}
catch (TargetInvocationException e)
{
throw e.InnerException;
}
}
オプション 2:
void DoDynamicCall()
{
MethodInfo method = /*referencing MyClass method void MyStaticFunction(int x)*/;
method.Invoke(null, new object[] { 5 });
}
私が本当に望んでいるのは、呼び出し元がこれを呼び出したDoDynamicCall
かのように例外を受け取ることです。
void DoDynamicCall()
{
MyClass.MyStaticFunction(5);
}
オプション 1とオプション 2の両方の利点を得る方法はありますか?
編集:
私が望んでいたオプション(その場で特別な新しいC#キーワードrethrow
を発明しました):
void DoDynamicCall()
{
MethodInfo method = /*referencing MyClass method void MyStaticFunction(int x)*/;
try
{
method.Invoke(null, new object[] { 5 });
}
catch (TargetInvocationException e)
{
//Magic "rethrow" keyword passes this exception
//onward unchanged, rather than "throw" which
//modifies the StackTrace, among other things
rethrow e.InnerException;
}
}
rethrow e;
代わりに次を使用できるため、これにより、この変人の必要もなくなります。
try { ... }
catch (Exception e)
{
if (...)
throw;
}
throw;
一般に、これは「catch ブロックに直接いなければならない」という要件から切り離す方法です。