在我的类中有一组私有方法,我需要根据输入值动态调用其中一个方法。调用代码和目标方法都在同一个实例中。代码如下所示:
MethodInfo dynMethod = this.GetType().GetMethod("Draw_" + itemType);
dynMethod.Invoke(this, new object[] { methodParams });
在这种情况下,GetMethod()将不会返回私有方法。我需要为GetMethod()提供什么BindingFlags,以便它可以定位私有方法?
调用任何方法,不管它在对象实例上的保护级别。享受吧!
public static object InvokeMethod(object obj, string methodName, params object[] methodParams)
{
var methodParamTypes = methodParams?.Select(p => p.GetType()).ToArray() ?? new Type[] { };
var bindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
MethodInfo method = null;
var type = obj.GetType();
while (method == null && type != null)
{
method = type.GetMethod(methodName, bindingFlags, Type.DefaultBinder, methodParamTypes, null);
type = type.BaseType;
}
return method?.Invoke(obj, methodParams);
}
微软最近修改了反射API,使大部分答案过时。以下内容应该适用于现代平台(包括Xamarin)。表格及UWP):
obj.GetType().GetTypeInfo().GetDeclaredMethod("MethodName").Invoke(obj, yourArgsHere);
或者作为扩展方法:
public static object InvokeMethod<T>(this T obj, string methodName, params object[] args)
{
var type = typeof(T);
var method = type.GetTypeInfo().GetDeclaredMethod(methodName);
return method.Invoke(obj, args);
}
注意:
如果所需的方法在obj的超类中,则必须显式地将T泛型设置为超类的类型。
如果方法是异步的,你可以使用await (Task) obj.InvokeMethod(…)。