Exemplo n.º 1
0
 public static object CallMethod(string methodName, bool staticMethod, Type typeToCall, object callee, IEnumerable<object> args, Type[] typeArgs, Engine engine)
 {
     var bindingFlags = (staticMethod ? BindingFlags.Static : BindingFlags.Instance) |
         BindingFlags.Public | BindingFlags.FlattenHierarchy;
     var methodInfo = null as MethodInfo;
     if (typeArgs != null)
     {
         // Use type arguments to choose overload.
         methodInfo = typeToCall.GetMethod(methodName, bindingFlags, null, typeArgs, null);
     }
     else
     {
         // Look for a matching method.
         var candidates = typeToCall.GetMethods(bindingFlags).Where(info => info.Name == methodName);
         var count = candidates.Count();
         if (count >= 1)
         {
             if (count == 1)
                 methodInfo = candidates.First();
             else
             {
                 // Use arguments to choose overload.
                 var types = args.Select(value => value != null ? value.GetType() : typeof(object));
                 methodInfo = typeToCall.GetMethod(methodName, bindingFlags, null, types.ToArray(), null);
                 if (methodInfo == null) engine.Throw("method overload not found: " + methodName);
             }
         }
     }
     if (methodInfo == null) engine.Throw("method not found: " + methodName);
     var parameters = methodInfo.GetParameters();
     var methodArgs = null as object[];
     if (HasParamsParameter(parameters))
     {
         var m = parameters.Length - 1;
         var initiaArgs = ConvertArguments(parameters.Take(m), args.Take(m));
         var paramsType = parameters[m].ParameterType.GetElementType();
         var remainingArgs = TypeHelper.CreateArray(args.Skip(m).ToArray(), paramsType);
         methodArgs = initiaArgs.Concat(new object[] { remainingArgs }).ToArray();
     }
     else
     {
         if (parameters.Length != args.Count()) engine.Throw("argument count mismatch: {0} != {1}", parameters.Length, args.Count());
         methodArgs = ConvertArguments(parameters, args).ToArray();
     }
     bool trace = engine.ShouldTrace(TraceFlags.Call);
     if (trace)
     {
         TraceCall("args", methodName, args, engine);
         TraceCall("methodArgs", methodName, methodArgs, engine);
     }
     var result = methodInfo.Invoke(callee, methodArgs);
     if (trace) engine.Trace(TraceFlags.Call, "Call {0} = {1}", methodName, result);
     return result;
 }