static bool FindMethodWithoutEqualParameterTypes(object obj, string name, object[] parameters, out Metadata.Method methodVirtual, out MethodInfo methodNative, out object[] newParameters) { methodVirtual = null; methodNative = null; newParameters = null; //!!!!ref, out support //!!!!default parameters //virtual, public var provider = obj as Metadata.IMetadataProvider; if (provider != null) { foreach (var member in provider.MetadataGetMembers()) { var method = member as Metadata.Method; if (method != null && method.Name == name) { var inputParams = method.GetInputParameters(); if (inputParams.Length == parameters.Length) { for (int nParam = 0; nParam < inputParams.Length; nParam++) { var demandedType = inputParams[nParam].Type.GetNetType(); var value = parameters[nParam]; if (value != null) { if (!demandedType.IsAssignableFrom(value.GetType()) && !MetadataManager.CanAutoConvertType(value.GetType(), demandedType)) { goto next_member; } } else { if (demandedType.IsValueType) { goto next_member; } } } //found { methodVirtual = method; newParameters = new object[inputParams.Length]; for (int nParam = 0; nParam < inputParams.Length; nParam++) { var demandedType = inputParams[nParam].Type.GetNetType(); var value = parameters[nParam]; if (value != null) { if (demandedType == value.GetType()) { newParameters[nParam] = value; } else if (demandedType.IsAssignableFrom(value.GetType())) { newParameters[nParam] = Convert.ChangeType(value, demandedType); } else { newParameters[nParam] = MetadataManager.AutoConvertValue(value, demandedType); } } } break; } } } next_member :; } } //native if (methodVirtual == null) { var bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; if (provider == null) { bindingFlags |= BindingFlags.Public; } foreach (var method in obj.GetType().GetMethods(bindingFlags)) { if (method.Name == name) { var inputParams = new List <ParameterInfo>(); foreach (var p in method.GetParameters()) { if (!p.IsRetval) { inputParams.Add(p); } } if (inputParams.Count == parameters.Length) { for (int nParam = 0; nParam < inputParams.Count; nParam++) { var demandedType = inputParams[nParam].ParameterType; var value = parameters[nParam]; if (value != null) { if (!demandedType.IsAssignableFrom(value.GetType()) && !MetadataManager.CanAutoConvertType(value.GetType(), demandedType)) { goto next_member2; } } else { if (demandedType.IsValueType) { goto next_member2; } } } //found { methodNative = method; newParameters = new object[inputParams.Count]; for (int nParam = 0; nParam < inputParams.Count; nParam++) { var demandedType = inputParams[nParam].ParameterType; var value = parameters[nParam]; if (value != null) { if (demandedType == value.GetType()) { newParameters[nParam] = value; } else if (demandedType.IsAssignableFrom(value.GetType())) { newParameters[nParam] = Convert.ChangeType(value, demandedType); } else { newParameters[nParam] = MetadataManager.AutoConvertValue(value, demandedType); } } } break; } } } next_member2 :; } } return(methodVirtual != null || methodNative != null); }