/// <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="info"> /// MethodInfo for the method. /// </param> /// <param name="parameters"> /// Parameters to pass to method. /// </param> public static object CallMethod(object obj, MethodInfo info, params object[] parameters) { DynamicMethodHandle mh = GetCachedMethod(obj, info, parameters); if (mh == null || mh.DynamicMethod == null) { throw new NotImplementedException(info.Name + " not implemented."); } return(CallMethod(obj, mh, parameters)); }
/// <summary> /// Uses reflection to dynamically invoke a method /// if that method is implemented on the target object. /// </summary> /// <param name="obj"> /// Object containing method. /// </param> /// <param name="method"> /// Name of the method. /// </param> /// <param name="parameters"> /// Parameters to pass to method. /// </param> public static object CallMethodIfImplemented(object obj, string method, params object[] parameters) { DynamicMethodHandle mh = GetCachedMethod(obj, method, parameters); if (mh == null || mh.DynamicMethod == null) { return(null); } return(CallMethod(obj, mh, parameters)); }
/// <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; DynamicMemberMethod method = methodHandle.DynamicMethod; object[] inParams = null; if (parameters == null) { inParams = new object[] { null } } ; else { inParams = parameters; } if (methodHandle.HasFinalArrayParam) { int pCount = methodHandle.MethodParamsLength; // last param is a param array or only param is an array int 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 var paramList = new object[pCount]; for (int 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 + " method call failed.", 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)) return mh; lock (_methodCache) { if (!_methodCache.TryGetValue(key, out mh)) { mh = new DynamicMethodHandle(info, parameters); _methodCache.Add(key, mh); } } return mh; }
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)) { return(mh); } lock (_methodCache) { if (!_methodCache.TryGetValue(key, out mh)) { mh = new DynamicMethodHandle(info, parameters); _methodCache.Add(key, mh); } } return(mh); }
/// <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; DynamicMemberMethod method = methodHandle.DynamicMethod; object[] inParams = null; if (parameters == null) inParams = new object[] { null }; else inParams = parameters; if (methodHandle.HasFinalArrayParam) { int pCount = methodHandle.MethodParamsLength; // last param is a param array or only param is an array int 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 var paramList = new object[pCount]; for (int 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 + " method call failed.", ex); } return result; }