// Returning an array directly so that the enumeration in // UserDefinedConversion does not allocate memory private static MethodInfo[] GetUserDefinedConversionMethods(Type source, Type destination) { var query = new ConversionQuery(source, destination); if (!userConversionMethodsCache.ContainsKey(query)) { userConversionMethodsCache.Add(query, FindUserDefinedConversionMethods(query).ToArray()); } return(userConversionMethodsCache[query]); }
public static ConversionType GetRequiredConversion(Type source, Type destination) { var query = new ConversionQuery(source, destination); if (!conversionTypesCache.TryGetValue(query, out var conversionType)) { conversionType = DetermineConversionType(query); conversionTypesCache.Add(query, conversionType); } return(conversionType); }
private static IEnumerable <MethodInfo> FindUserDefinedConversionMethods(ConversionQuery query) { var source = query.source; var destination = query.destination; var sourceMethods = source.GetMethods(UserDefinedBindingFlags) .Where(m => m.IsUserDefinedConversion()); var destinationMethods = destination.GetMethods(UserDefinedBindingFlags) .Where(m => m.IsUserDefinedConversion()); return(sourceMethods.Concat(destinationMethods).Where ( m => m.GetParameters()[0].ParameterType.IsAssignableFrom(source) || source.IsAssignableFrom(m.GetParameters()[0].ParameterType) )); }
private static ConversionType DetermineConversionType(ConversionQuery query) { var source = query.source; var destination = query.destination; if (source == null) { if (destination.IsNullable()) { return(ConversionType.Identity); } else { return(ConversionType.Impossible); } } Ensure.That(nameof(destination)).IsNotNull(destination); if (RespectsIdentity(source, destination)) { return(ConversionType.Identity); } else if (IsUpcast(source, destination)) { return(ConversionType.Upcast); } else if (IsDowncast(source, destination)) { return(ConversionType.Downcast); } // Disabling *.ToString conversion, because it's more often than otherwise very confusing /*else if (ExpectsString(source, destination)) * { * return ConversionType.ToString; * }*/ else if (HasImplicitNumericConversion(source, destination)) { return(ConversionType.NumericImplicit); } else if (HasExplicitNumericConversion(source, destination)) { return(ConversionType.NumericExplicit); } else if (HasUnityHierarchyConversion(source, destination)) { return(ConversionType.UnityHierarchy); } else if (HasEnumerableToArrayConversion(source, destination)) { return(ConversionType.EnumerableToArray); } else if (HasEnumerableToListConversion(source, destination)) { return(ConversionType.EnumerableToList); } else { var userDefinedConversionType = GetUserDefinedConversionType(source, destination); if (userDefinedConversionType != ConversionType.Impossible) { return(userDefinedConversionType); } } return(ConversionType.Impossible); }