4

現在.NET 3.5を使用しており、アプリケーションの一部は動的呼び出しを使用しています(MethodBase.Invokeを使用)

名前付きパラメーター (.NET 4) と動的呼び出しを組み合わせて、次のようなことを実行できるかどうか疑問に思っています。

// Dictionary that holds parameter name --> object mapping
var parameters = new Dictionary<string, object>();

// Add parameters ....

// Invoke where each parameter will match the one from the method signature.
methodInfo.Invoke(obj, parameters);

このオプションをそのまま使用できる API はありますか? そうでない場合、これを実行するためのソリューションを開発することは可能ですか?

編集:

この問題を再考すると、コンパイラが引数リストに基づいてメソッド呼び出しを実際に照合する必要がある場合と似ているように思えます。おそらく、これを簡単に実行できるコンパイラ API (または新しい Roslyn プロジェクト) があるでしょうか? (自分でコーディングしないと、エラーが発生する可能性があります)。

4

3 に答える 3

17

次のようなコードを使用できます。

public static class ReflectionExtensions {

    public static object InvokeWithNamedParameters(this MethodBase self, object obj, IDictionary<string, object> namedParameters) { 
        return self.Invoke(obj, MapParameters(self, namedParameters));
    }

    public static object[] MapParameters(MethodBase method, IDictionary<string, object> namedParameters)
    {
        string[] paramNames = method.GetParameters().Select(p => p.Name).ToArray();
        object[] parameters = new object[paramNames.Length];
        for (int i = 0; i < parameters.Length; ++i) 
        {
            parameters[i] = Type.Missing;
        }
        foreach (var item in namedParameters)
        {
            var paramName = item.Key;
            var paramIndex = Array.IndexOf(paramNames, paramName);
            if (paramIndex >= 0)
            {
                parameters[paramIndex] = item.Value;
            }
        }
        return parameters;
    }
}

そして、次のように呼び出します。

var parameters = new Dictionary<string, object>();
// Add parameters ...
methodInfo.InvokeWithNamedParameters(obj, parameters);
于 2012-10-25T16:02:03.337 に答える
1

この記事の助けを借りてパラメータ名を取得できますメソッドパラメータの名前を取得するにはどうすればよいですか?次に、ここで説明されているように、それらを並べ替えて呼び出すことができます。リフレクション:パラメーターを使用してメソッドを呼び出す方法

于 2012-10-25T15:31:23.293 に答える
1

.net4 には、名前付き/オプションのパラメーターを含む遅延呼び出し用の DLR API を簡単に使用できるオープンソース フレームワーク ImpromptuInterface (nuget にあります) があります。

var result = Impromptu.InvokeMember(target, "MyMethod", parameters.Select(pair=>  InvokeArg.Create(pair.Key, pair.Value)).Cast<object>().ToArray());
于 2012-10-29T20:06:31.353 に答える