繁体   English   中英

通过反射调用方法而不会获得TargetInvocationException

[英]Invoke a method through reflection without getting TargetInvocationException

我找到了一个使用反射的方法(并得到了它的MethodInfo )。 抛出异常时,如何在不获取TargetInvocationException情况下调用它?

更新

我正在创建一个命令实现,其中命令由实现的类处理

public interface ICommandHandler<T> where T : class, ICommand
{
    public void Invoke(T command);
}

由于有一个调度程序负责查找并将所有处理程序映射到正确的命令,因此我不能直接调用方法,而是使用反射。 就像是:

var handlerType = tyepof(IHandlerOf<>).MakeGenericType(command.GetType());
var method = handlerType.GetMethod("Invoke", new [] { command.GetType() });
method.Invoke(theHandler, new object[]{command});

它工作正常,但我希望所有异常都传递给调用该命令的代码。

这样调用者就可以使用:

try
{
    _dispatcher.Invoke(new CreateUser("Jonas", "Gauffin"));
}
catch (SomeSpecificException err)
{
    //handle it.
}

而不是必须捕获TargetInvocationException

(我知道我可以抛出内部异常,但由于堆栈跟踪被破坏,这是非常没用的)

UPDATE2

是一个可能的解决方案..

但它似乎更像是一个黑客。 有没有更好的解决方案? 也许用表情或什么?

创建一个DelegateMethodInfo (通过的重载之一Delegate.CreateDelegate )和调用该代替。 不会将方法抛出的任何异常包装在类似MethodInfo.InvokeTargetInvocationException中。

class Foo
{
    static void ThrowingMethod()
    {
        throw new NotImplementedException();
    }

    static MethodInfo GetMethodInfo()
    {
        return typeof(Foo)
                .GetMethod("ThrowingMethod", BindingFlags.NonPublic | BindingFlags.Static);
    }

    // Will throw a NotImplementedException
    static void DelegateWay()
    {
        Action action = (Action)Delegate.CreateDelegate
                                    (typeof(Action), GetMethodInfo());
        action();
    }

    // Will throw a TargetInvocationException 
    // wrapping a NotImplementedException
    static void MethodInfoWay()
    {
        GetMethodInfo().Invoke(null, null);
    }
}

编辑

(正如OP指出的那样,DynamicInvoke不会在这里工作,因为它也包装了)

根据您的更新,我会使用dynamic

((dynamic)theHandler).Invoke(command);

你不能。 这是通过反射调用方法传播异常的指定方式。 如果希望效果是抛出的原始异常,则可以始终捕获TargetInvocationException ,然后抛出通过InnerException属性获取的“内部”异常。

(请注意,您将丢失原始堆栈跟踪。可能有一种方法可以防止这种情况,但这很棘手。我相信在.NET 4.5中可能会有更多支持;我不确定。)

您可以在mehtodinfo实例上调用Invoke,但调用的第一个参数是目标(方法信息所属的对象)。 如果你通过它并且有权调用它,你就不应该得到例外。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM