public object Invoke(MethodBase method, object target, object[] arguments, MethodBase caller, BindingFlags invokeAttr = BindingFlags.Default, Binder binder = null, CultureInfo culture = null) { if (binder != null) { throw new NotSupportedException(); } if (method.DeclaringType.ContainsGenericParameters) { throw new Exception($"Attempted to call method {method} on open generic type {method.DeclaringType}."); } if ((method as MethodInfo)?.ContainsGenericParameters ?? false) { throw new Exception($"Attempted to call open generic method {method}."); } if (method.IsConstructor && !method.IsStatic && (target == null)) { return(InvokeConstructorForNewObject((ConstructorInfo)method, arguments, caller)); } object result; if (TryInvokeSpecialMethod(method, arguments, caller, out result)) { return(result); } if (!method.IsStatic) { if (target == null) { throw new NullReferenceException($"Attempted to call instance method {method.Name} on null reference."); } var custom = target as ICustomInvoker; if (custom != null) { return(custom.Invoke(method, arguments, invokeAttr, binder, culture)); } } if (!(method is IInterpretedMethodBase)) { var unwrapped = ObjectWrapper.UnwrapIfRequired(target); if (!(unwrapped is INonRuntimeObject)) { if (method.DeclaringType.IsInterface && !unwrapped.GetType().IsArray) { method = GetMatchingMethod(unwrapped.GetType(), (MethodInfo)method); } return(method.Invoke(unwrapped, invokeAttr, binder, arguments, culture)); } } if (!method.IsStatic && !method.IsConstructor) { var targetType = TypeSupport.GetTypeOf(target); if (method.DeclaringType != targetType) { method = GetMatchingMethod(targetType, (MethodInfo)method); } } var interpreted = method as IInterpretedMethodBase; if (interpreted == null) { throw new Exception($"Cannot invoke runtime method {method} on non-runtime instance {target}."); } return(_interpreter.InterpretCall( method.DeclaringType.GetGenericArguments(), (MethodBase)interpreted, (MethodDefinition)interpreted.InvokableDefinition, method.GetGenericArguments(), target, arguments )); }