如何在 c# 中检查函数所需的参数(类型、名称和顺序)?
我想要做的是以下内容:
在一个方法中,我有 4 个不同类型的变量(double、int、string、enum 等)。所有这些变量都需要传递给合适的函数(我的意思是方法)。有三个候选函数,每个函数都需要不同的参数集。
代码必须检查哪个函数有 4 个类型完全匹配的输入参数,并将我的变量传递给这个函数。如果没有找到匹配的函数,我的方法应该创建一个异常。提前感谢您的帮助。
小威
如何在 c# 中检查函数所需的参数(类型、名称和顺序)?
我想要做的是以下内容:
在一个方法中,我有 4 个不同类型的变量(double、int、string、enum 等)。所有这些变量都需要传递给合适的函数(我的意思是方法)。有三个候选函数,每个函数都需要不同的参数集。
代码必须检查哪个函数有 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。在签名中,它会变得更加复杂。
如果参数的顺序不正确,那么您需要为每个排列尝试Zip
/ (可能切割整个分支,这可能通过回溯算法更容易,但它仍然可能非常耗时)。All
parameters
尝试这个:
类程序{静态无效主要(字符串[]参数){
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),并且它被标记为反射,我会回答记住这一点)
通过反思,您可以获得根据您提到的类型做出决定所需的所有信息。例如,MethodInfo 包含两个可能与您相关的方法:
ReturnType:http: //msdn.microsoft.com/en-us/library/system.reflection.methodinfo.returntype.aspx
获取参数:http : //msdn.microsoft.com/en-us/library/system.reflection.methodbase.getparameters.aspx
找到您要查找的函数后,您可以使用 .. Invoke 方法调用它:
http://msdn.microsoft.com/en-us/library/a89hcwhh.aspx
没有更具体的例子,过程是:
对于一个类中的所有 MethodInfo(s):
正如评论中提到的,第三点可能是困难的部分。这是编译器在选择最匹配的重载方法时通常会做的事情(即,当它从多个具有相同名称的方法中选择时,仅基于类型)。
但是,您的情况可能比一般问题更简单:确定有限数量的方法之一,具有固定数量的参数,按顺序请求的类型(以及确切的类型,即不需要隐式casts) 可以很容易地实现。您应该提供更多上下文。
如果您有有效的方法信息,请将参数作为对象数组传递以进行调用。警告:反射效率不是很高(它也不是很慢!)。仅当您确实需要它时才应该这样做,例如在一个好的 OO 设计对您没有帮助的情况下。