我们目前正在使用.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项目)可以轻松地做到这一点? (没有自己编码,可能容易出错)。
答案 0 :(得分:15)
您可以使用以下代码:
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);
parameters[paramIndex] = item.Value;
}
return parameters;
}
}
然后像这样称呼它:
var parameters = new Dictionary<string, object>();
// Add parameters ...
methodInfo.InvokeWithNamedParameters(obj, parameters);
答案 1 :(得分:1)
您可以在本文How can you get the names of method parameters?的帮助下获取参数名称,然后您可以重新排序它们以按照此处所述调用它们Reflection: How to Invoke Method with parameters
答案 2 :(得分:1)
使用.net4,我有一个开源框架ImpromptuInterface(在nuget中找到),可以很容易地使用late invocation including named/optional parameters的DLR apis。
var result = Impromptu.InvokeMember(target, "MyMethod", parameters.Select(pair=> InvokeArg.Create(pair.Key, pair.Value)).Cast<object>().ToArray());