Я хочу динамически вызывать объект 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
):
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".