/// <summary> /// Obtains a list of all methods with the given <paramref name="methodName"/> on the given /// <paramref name="obj" />, and invokes the best match for the supplied parameters. /// TryCallMethod is very liberal and attempts to convert values that are not otherwise /// considered compatible, such as between strings and enums or numbers, Guids and byte[16], etc. /// </summary> /// <param name="obj">The type of which an instance should be created.</param> /// <param name="methodName">The name of the overloaded methods.</param> /// <param name="mustUseAllParameters">Specifies whether all supplied parameters must be used in the /// invocation. Unless you know what you are doing you should pass true for this parameter.</param> /// <param name="parameterNames">The names of the supplied parameters.</param> /// <param name="parameterTypes">The types of the supplied parameters.</param> /// <param name="parameterValues">The values of the supplied parameters.</param> /// <returns>The result of the invocation.</returns> public static object TryCallMethod(this object obj, string methodName, bool mustUseAllParameters, string[] parameterNames, Type[] parameterTypes, object[] parameterValues) { bool isStatic = obj is Type; var type = isStatic ? obj as Type : obj.GetType(); var names = parameterNames ?? new string[0]; var types = parameterTypes ?? new Type[0]; var values = parameterValues ?? new object[0]; if (names.Length != values.Length || names.Length != types.Length) { throw new ArgumentException("Mismatching name, type and value arrays (must be of identical length)."); } MethodMap map = MapFactory.DetermineBestMethodMatch(type.Methods(methodName).Cast <MethodBase>(), mustUseAllParameters, names, types, values); return(isStatic ? map.Invoke(values) : map.Invoke(obj, values)); }
/// <summary> /// Creates an instance of the given <paramref name="type"/> using the public properties of the /// supplied <paramref name="sample"/> object as input. /// This method will try to determine the least-cost route to constructing the instance, which /// implies mapping as many properties as possible to constructor parameters. Remaining properties /// on the source are mapped to properties on the created instance or ignored if none matches. /// TryCreateInstance is very liberal and attempts to convert values that are not otherwise /// considered compatible, such as between strings and enums or numbers, Guids and byte[], etc. /// </summary> /// <returns>An instance of <paramref name="type"/>.</returns> public static object TryCreateInstance(this Type type, object sample) { Type sourceType = sample.GetType(); SourceInfo sourceInfo = sourceInfoCache.Get(sourceType); if (sourceInfo == null) { sourceInfo = new SourceInfo(sourceType); sourceInfoCache.Insert(sourceType, sourceInfo); } object[] paramValues = sourceInfo.GetParameterValues(sample); MethodMap map = MapFactory.PrepareInvoke(type, sourceInfo.ParamNames, sourceInfo.ParamTypes, paramValues); return(map.Invoke(paramValues)); }
/// <summary> /// Creates an instance of the given <paramref name="type"/> using the supplied parameter information as input. /// This method will try to determine the least-cost route to constructing the instance, which /// implies mapping as many properties as possible to constructor parameters. Remaining properties /// on the source are mapped to properties on the created instance or ignored if none matches. /// TryCreateInstance is very liberal and attempts to convert values that are not otherwise /// considered compatible, such as between strings and enums or numbers, Guids and byte[], etc. /// </summary> /// <param name="type">The type of which an instance should be created.</param> /// <param name="parameterNames">The names of the supplied parameters.</param> /// <param name="parameterTypes">The types of the supplied parameters.</param> /// <param name="parameterValues">The values of the supplied parameters.</param> /// <returns>An instance of <paramref name="type"/>.</returns> public static object TryCreateInstance(this Type type, string[] parameterNames, Type[] parameterTypes, object[] parameterValues) { var names = parameterNames ?? new string[0]; var types = parameterTypes ?? new Type[0]; var values = parameterValues ?? new object[0]; if (names.Length != values.Length || names.Length != types.Length) { throw new ArgumentException("Mismatching name, type and value arrays (must be of identical length)."); } MethodMap map = MapFactory.PrepareInvoke(type, names, types, values); return(map.Invoke(values)); }