如何在 c# 中检查函数的必需参数(类型、名称和顺序)?
我想做的是:
在一个方法中,我有 4 个不同类型的变量(双精度、整数、字符串、枚举等)。所有这些变量都需要传递给合适的函数(我的意思是方法)。有三个候选函数,每个函数都需要不同的参数集。
代码必须检查哪个函数有 4 个类型完全匹配的输入参数,并将我的变量传递给这个函数。如果未找到匹配的函数,我的方法应该创建一个异常。提前感谢任何帮助。
瑟 琳 娜
如果您知道给定的参数顺序正确,那么您可以查看每个参数是否可以从该位置的签名类型中分配,并且这并不是那么糟糕:
public static MethodInfo CallMethod(MethodInfo[] candicateMethods, object instance, object[] parameters)
{
foreach (var method in candicateMethods)
{
if (CallMethod(method, instance, parameters))
return method;
}
return null;
}
private static bool CallMethod(MethodInfo method, object instance, object[] parameters)
{
if (method.GetParameters().Length == parameters.Length
&& method.GetParameters()
.Zip(parameters, (a, b) => new
{
Signature = a.ParameterType,
Candidate = b.GetType()
})
.All(pair => pair.Signature.IsAssignableFrom(pair.Candidate)))
{
method.Invoke(instance, parameters);
return true;
}
return false;
}
如果你还需要在签名中处理out/ref/params/etc.,它会变得更加复杂。
如果参数顺序不正确,则需要尝试对parameters
的每个排列进行Zip
/All
(可能会切割整个分支,通过回溯算法可能更容易,但仍然可能非常耗时)。
试试这个:
班级课程 { 静态空 主(字符串[] 参数) {
var method = typeof(Program).GetMethod("test");
string parameterTypes = string.Join(", ", method.GetParameters().Select(x=>x.ParameterType));
Console.WriteLine("{0} ({1})",
method.Name,
parameterTypes);
Console.ReadKey();
}
public void test(int a, string c)
{
}
}
(因为问题要求"运行时"匹配(vs.compile time),并且它被标记为反射,我会记住这一点)
通过反思,您可以获得根据您提到的类型做出决定所需的所有信息。例如,方法信息包含两个可能与您相关的方法:
返回类型:http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.returntype.aspx
获取参数:http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getparameters.aspx
找到所需的函数后,可以使用 .. 调用它。调用方法:
http://msdn.microsoft.com/en-us/library/a89hcwhh.aspx
如果没有更具体的示例,该过程为:
对于类中的所有方法信息:
- 获取参数和返回类型
- 检查返回类型(如果需要)
- 如果参数中的类型和返回类型匹配,则完成
正如评论中提到的,第三点可能是困难的部分。这是编译器在选择最佳匹配重载方法时(即,当它仅根据类型从具有相同名称的多个方法中进行选择时)通常执行的操作。
但是,您的情况可能比一般问题简单:确定有限数量的方法之一,具有固定数量的参数,按顺序使用请求的类型(以及确切的类型,即不需要隐式强制转换)可以很容易地实现。您应该提供更多上下文。
如果您有有效的方法信息,请将参数作为要调用的对象数组传递。警告:反射不是超级有效(它也不是很慢!只有在您真正需要时才应该这样做,例如,在良好的OO设计对您没有帮助的情况下。