/// <summary> /// Uses reflection to dynamically invoke a method, /// throwing an exception if it is not implemented /// on the target object. /// </summary> /// <param name="obj"> /// Object containing method. /// </param> /// <param name="methodHandle"> /// MethodHandle for the method. /// </param> /// <param name="parameters"> /// Parameters to pass to method. /// </param> private static object CallMethod(object obj, DynamicMethodHandle methodHandle, params object[] parameters) { object result = null; var method = methodHandle.DynamicMethod; object[] inParams = null; if (parameters == null) { inParams = new object[] { null } } ; else { inParams = parameters; } if (methodHandle.HasFinalArrayParam) { var pCount = methodHandle.MethodParamsLength; // last param is a param array or only param is an array var extras = inParams.Length - (pCount - 1); // 1 or more params go in the param array // copy extras into an array object[] extraArray = GetExtrasArray(extras, methodHandle.FinalArrayElementType); Array.Copy(inParams, extraArray, extras); // copy items into new array object[] paramList = new object[pCount]; for (var pos = 0; pos <= pCount - 2; pos++) { paramList[pos] = parameters[pos]; } paramList[paramList.Length - 1] = extraArray; // use new array inParams = paramList; } try { result = methodHandle.DynamicMethod(obj, inParams); } catch (Exception ex) { throw new CallMethodException(methodHandle.MethodName + " " + Resources.MethodCallFailed, ex); } return(result); }
private static DynamicMethodHandle GetCachedMethod(object obj, MethodInfo info, params object[] parameters) { var key = new MethodCacheKey(obj.GetType().FullName, info.Name, GetParameterTypes(parameters)); DynamicMethodHandle mh = null; if (!_methodCache.TryGetValue(key, out mh)) { lock (_methodCache) { if (!_methodCache.TryGetValue(key, out mh)) { mh = new DynamicMethodHandle(info, parameters); _methodCache.Add(key, mh); } } } return(mh); }