public static bool Convert(object val, Type targetType, out object result) { result = val; // Trivial cases if (val == null) { // Cannot convert null to value type return(!targetType.IsValueType); } if (targetType.IsAssignableFrom(val.GetType())) { return(true); } // Custom type conversions if (_customTypeConverter != null) { if (_customTypeConverter(val, targetType, out result)) { return(true); } } // TODO: typeof(Nullable<T>) // Built-in type conversions if (val.GetType() == typeof(string) && targetType == typeof(Type)) { // string -> Type result = Type.GetType(val.ToString()); return(result != null); } // Enumerations if (val.GetType() == typeof(string) && targetType.IsEnum) { // string -> Enum result = Enum.Parse(targetType, (string)val); return(true); } // String target type must be done before enumerations are tried - else, the string will be treated as enumeration if (targetType.IsAssignableFrom(typeof(string))) { // * -> string result = val.ToString(); return(true); } // Collection types Type enumerableType; Type entryType; ReflectionHelper.FindImplementedEnumerableType(targetType, out enumerableType, out entryType); if (enumerableType != null) // Targets IList, ICollection, IList<>, ICollection<> { ICollection col; if (!ToCollection(val, entryType, out col)) { return(false); } List <object> resultList = col.Cast <object>().ToList(); result = resultList; return(true); } ICollection sourceCol = val as ICollection; if (sourceCol != null && sourceCol.Count == 1) // From collection to non-collection target { // Use the first (single) item of a collection or dictionary IEnumerator enumerator = sourceCol.GetEnumerator(); enumerator.MoveNext(); object item = enumerator.Current; if (Convert(item, targetType, out result)) // Single collection item { return(true); } KeyValuePair <object, object>?kvp = item as KeyValuePair <object, object>?; if (kvp.HasValue && Convert(kvp.Value.Value, targetType, out result)) // Value of single dictionary entry - generic dictionary { IDisposable d = kvp.Value.Key as IDisposable; if (d != null) { d.Dispose(); } return(true); } DictionaryEntry?entry = item as DictionaryEntry?; if (entry.HasValue && Convert(entry.Value.Value, targetType, out result)) // Value of single dictionary entry - legacy dictionary { IDisposable d = entry.Value.Key as IDisposable; if (d != null) { d.Dispose(); } return(true); } } // Simple type conversions System.ComponentModel.TypeConverter tc = TypeDescriptor.GetConverter(targetType); if (tc != null && tc.CanConvertFrom(val.GetType())) { try { result = tc.ConvertFrom(null, CultureInfo.InvariantCulture, val); return(true); } catch { } } tc = TypeDescriptor.GetConverter(val); if (tc != null && tc.CanConvertTo(targetType)) { result = tc.ConvertTo(val, targetType); return(true); } return(false); }