Ejemplo n.º 1
0
        // 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]);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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)
                   ));
        }
Ejemplo n.º 4
0
        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);
        }