Preservando exceções de métodos invocados dinamicamente

RelacionadoRelacionado

Eu quero invocar dinamicamente umMethodInfo objeto e ter quaisquer exceções que são jogadas de dentro para fora como se fosse chamado normalmente.

Eu tenho duas opções, parece. Eles estão descritos abaixo.

Opção 1 mantém o tipo da exceção lançada porMyStaticFunction, mas oStackTrace está arruinado por causa dathrow.

opção 2 mantém oStackTrace da exceção, mas o tipo da exceção é sempreTargetInvocationException. Posso tirar oInnerException e seu tipo, mas isso significa que eu não posso escrever isso por exemplo:

try { DoDynamicCall(); }
catch (MySpecialException e) { /* special handling */ }

Opção 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;
    }
}

Opção 2:

void DoDynamicCall()
{
    MethodInfo method = /*referencing MyClass method void MyStaticFunction(int x)*/;
    method.Invoke(null, new object[] { 5 });
}

O que eu realmente quero é para os chamadoresDoDynamicCall para receber exceções como se tivessem chamado isso:

void DoDynamicCall()
{
    MyClass.MyStaticFunction(5);
}

Existe uma maneira de obter os benefícios de ambosOpção 1 eopção 2?

Editar:

oopção que eu gostaria de ter (inventada nova palavra-chave especial C #rethrow no local):

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;
    }
}

Isso também eliminaria a necessidade desse esquisitão, porque você poderia usarrethrow e; em vez de:

try { ... }
catch (Exception e)
{
    if (...)
        throw;
}

Em geral, seria uma maneira de dissociarthrow; a partir do requisito "Eu tenho que estar diretamente em um bloco de captura".

questionAnswers(4)

yourAnswerToTheQuestion