using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Reflection;
namespace ExpressionsParser {
///
/// Invoke object's method that is most compatible with provided arguments
///
internal class InvokeMethod {
public object TargetObject { get; set; }
public string MethodName { get; set; }
public InvokeMethod(object o, string methodName) {
TargetObject = o;
MethodName = methodName;
}
protected MethodInfo FindMethod(Type[] argTypes) {
if (TargetObject is Type) {
// static method
#if NET40
return ((Type)TargetObject).GetMethod(MethodName, BindingFlags.Static | BindingFlags.Public);
#else
return ((Type)TargetObject).GetRuntimeMethod(MethodName, argTypes);
#endif
}
#if NET40
return TargetObject.GetType().GetMethod(MethodName, argTypes);
#else
return TargetObject.GetType().GetRuntimeMethod(MethodName, argTypes);
#endif
}
protected IEnumerable GetAllMethods() {
if (TargetObject is Type) {
#if NET40
return ((Type)TargetObject).GetMethods(BindingFlags.Static | BindingFlags.Public);
#else
return ((Type)TargetObject).GetRuntimeMethods();
#endif
}
#if NET40
return TargetObject.GetType().GetMethods();
#else
return TargetObject.GetType().GetRuntimeMethods();
#endif
}
public object Invoke(object[] args) {
Type[] argTypes = new Type[args.Length];
for (int i = 0; i < argTypes.Length; i++)
argTypes[i] = args[i] != null ? args[i].GetType() : typeof(object);
// strict matching first
MethodInfo targetMethodInfo = FindMethod(argTypes);
// fuzzy matching
if (targetMethodInfo==null) {
var methods = GetAllMethods();
foreach (var m in methods)
if (m.Name==MethodName &&
m.GetParameters().Length == args.Length &&
CheckParamsCompatibility(m.GetParameters(), argTypes, args)) {
targetMethodInfo = m;
break;
}
}
if (targetMethodInfo == null) {
string[] argTypeNames = new string[argTypes.Length];
for (int i=0; i