static bool ParamArrayMatchs(object[] args, int index, Type dest, ArgumentConversions conversions) { var argConversions = new ArgumentConversions(args.Length - index); // check first parameter type matches for (int i = 0, current = index; current < args.Length; i++, current++) { var arg = args[current]; if (arg is null) { if (dest.IsValueType && !IsNullableType(dest)) { return(false); } } else { var src = arg.GetType(); if (!TypeUtils.AreReferenceAssignable(dest, src)) { if (TryImplicitConvert(src, dest, out MethodInfo opImplict) == false) { return(false); } argConversions.Add(new ParamConversion(i, opImplict)); } } } conversions.Add(new ParamArrayConversion(index, dest, argConversions)); return(true); }
public static MethodInfo FindSetIndexer(this Type type, object[] args, out ArgumentConversions conversions) { conversions = new ArgumentConversions(args.Length); if (type.IsArray) { var m = type.GetMethod("Set", TypeUtils.PublicInstance); //for array no indexer we have to use Set Method if (MatchesArguments(m, args, conversions)) { return(m); } return(null); } foreach (var item in type.GetDefaultMembers()) { if (item.MemberType == MemberTypes.Property) { var p = (PropertyInfo)item; if (p.CanWrite) { var m = p.GetSetMethod(true); if (MatchesArguments(m, args, conversions)) { return(m); } } } } return(null); }
public static bool TryFindMethod(this Type type, string name, object[] args, out MethodInfo method, out ArgumentConversions conversions) { conversions = new ArgumentConversions(args.Length); return(type.IsInterface ? TryFindInterfaceMethod(type, name, args, out method, conversions) : type.IsDefined(typeof(RegisterAttribute), false) ? FindMethods(type, name, TypeUtils.AnyPublic, args, out method, conversions) : TryFindSystemMethod(name, type, TypeUtils.AnyPublic, args, out method, conversions)); }
Any IDynamicInvocable.Invoke(string name, params Any[] args) { var actualArgs = Any.GetArgs(args); var i = FindEntry(name); if (i >= 0 && entries[i].Value is System.Delegate del) { var conversions = new ArgumentConversions(args.Length); var method = del.GetType().GetMethod(nameof(System.Action.Invoke)); if (method.MatchesArguments(actualArgs, conversions)) { return(Any.op_Implicit(del.DynamicInvoke(actualArgs))); } } return(default(Any)); }
public MethodInvoker(object target, MethodInfo method, ArgumentConversions conversions) { Target = target; Method = method; Conversions = conversions; }
public ParamArrayConversion(int index, Type type, ArgumentConversions conversions) : base(index) { Type = type; Conversions = conversions; }
public static bool MatchesArguments(this MethodBase method, object[] args, ArgumentConversions conversions) { var parameters = method.GetParameters(); // arg length var length = args.Length; // no arg int argCount = parameters.Length; if (argCount == 0 && length > 0) { return(false); } int i; for (i = 0; i < argCount; i++) { var param = parameters[i]; var dest = param.ParameterType; if (param.IsDefined(typeof(ParamArrayAttribute), false)) { // parameters is extra example print(string, params string[] args) and print('hello') // in this case 2 and 1 if (argCount > length) { conversions.Add(new ParamArrayConversion(i, dest.GetElementType())); return(true); } //No further check required if matchs return(ParamArrayMatchs(args, i, dest.GetElementType(), conversions)); } // matches current index if (i >= length) { // method has one more parameter so skip return(conversions.Recycle()); } var arg = args[i]; if (arg is null) { if (dest.IsValueType && !IsNullableType(dest)) { return(conversions.Recycle()); } } else { var src = arg.GetType(); if (!TypeUtils.AreReferenceAssignable(dest, src)) { if (TryImplicitConvert(src, dest, out MethodInfo opImplict) == false) { return(conversions.Recycle()); } conversions.Add(new ParamConversion(i, opImplict)); } } } if (i == length) { return(true); } return(conversions.Recycle()); }
/// Current Declared Indexer can get public static MethodInfo FindSetIndexer(this Type type, object[] indices, object value, out ArgumentConversions conversions, out object[] args) { int length = indices.Length; args = new object[length + 1]; indices.CopyTo(args, 0); args[length] = value; return(FindSetIndexer(type, args, out conversions)); }
private static bool TryFindSystemMethod(string name, Type type, BindingFlags flags, object[] args, out MethodInfo method, ArgumentConversions conversions) { if (type != null) { foreach (MethodInfo m in type.GetMethods(flags)) { if (m.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && MatchesArguments(m, args, conversions)) { method = m; return(true); } } } method = null; return(false); }
static bool TryFindInterfaceMethod(this Type type, string name, object[] args, out MethodInfo method, ArgumentConversions conversions) { if (TryFindSystemMethod(name, type, TypeUtils.PublicInstance, args, out method, conversions)) { return(true); } var types = type.GetInterfaces(); for (int i = 0; i < types.Length; i++) { type = types[i]; if (TryFindSystemMethod(name, type, TypeUtils.PublicInstance, args, out method, conversions)) { return(true); } } return(false); }
static bool FindMethods(this Type type, string name, BindingFlags flags, object[] args, out MethodInfo method, ArgumentConversions conversions) { if (type != null) { var methods = type.GetMethods(flags); for (int i = 0; i < methods.Length; i++) { var m = methods[i]; var attrs = (RegisterAttribute[])m.GetCustomAttributes(typeof(RegisterAttribute), false); if (attrs.Length > 0 && attrs[0].Match(name) && MatchesArguments(m, args, conversions)) { method = m; return(true); } } return(FindMethods(type.BaseType, name, TypeUtils.PublicStatic, args, out method, conversions)); } method = null; return(false); }