我想动态调用一个MethodInfo
对象,并让从它内部抛出的任何异常向外传递,就好像它被正常调用一样。
我似乎有两个选择。它们概述如下。
选项 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的好处?
编辑:
我希望拥有的选项(rethrow
当场发明了特殊的新 C# 关键字):
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 块中”的要求脱钩的方法。