6

リフレクションを使用する方法を見つけました(そしてそれを手に入れましたMethodInfo)。TargetInvocationException例外がスローされたときに取得せずに呼び出すにはどうすればよいですか?

アップデート

コマンドを実装するクラスによってコマンドが処理されるコマンド実装を作成しています

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

すべてのハンドラーの検索とマップを処理するディスパッチャーが1つあるため、メソッドを直接呼び出すことはできませんが、リフレクションを使用します。何かのようなもの:

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

これが可能な解決策です。

しかし、それはハックのようです。より良い解決策はありませんか?多分表現か何かで?

4

3 に答える 3

5

(のオーバーロードの1つを介して)Delegateからを作成し、代わりにそれを呼び出します。これ、メソッドによってスローされた例外をlike内にラップしません。MethodInfoDelegate.CreateDelegateTargetInvocationExceptionMethodInfo.Invoke

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);
于 2012-06-21T14:11:10.813 に答える
3

できません。これは、リフレクションを介してメソッドを呼び出すことによって例外が伝播される指定された方法です。スローされる元の例外をエフェクトにする場合は、プロパティTargetInvocationExceptionを介して取得した「内部」例外をいつでもキャッチしてスローできます。InnerException

(元のスタックトレースが失われることに注意してください。これを防ぐ方法はあるかもしれませんが、注意が必要です。.NET4.5では、これがさらにサポートされる可能性があります。よくわかりません。)

于 2012-06-21T14:10:38.893 に答える
-1

mehtodinfoインスタンスでInvokeを呼び出すことができますが、呼び出しの最初の引数はターゲット(メソッドinfoが属するオブジェクト)です。これに合格し、それを呼び出すためのアクセス権がある場合、例外は発生しません。

于 2012-06-21T14:10:31.837 に答える