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