private static bool FromStringToTypeProxy(string from, object defaultVal, Type xType, out object result)
        {
            if (TypeDeterminer.IsNumericType(xType))
            {
                return(FromStringToNumericType(from, defaultVal, xType, out result));
            }
            if (TypeDeterminer.IsGuidType(xType))
            {
                return(FromStringToGuid(from, defaultVal, out result));
            }
            if (TypeDeterminer.IsDateTimeTypes(xType))
            {
                return(FromStringToDateTimeType(from, defaultVal, xType, out result));
            }
            if (TypeDeterminer.IsEnumType(xType))
            {
                return(FromStringToEnum(from, xType, defaultVal, out result));
            }
            if (TypeDeterminer.IsOriginObject(xType))
            {
                result = from;
                return(true);
            }

            var _ = TypeDeterminer.GetDefaultValue(xType);

            result = from.Is(xType, t => _ = t) ? _ : defaultVal;
            return(false);
        }
        private static bool FromStringToTypeProxy <X>(string from, X defaultVal, Type xType, out object result)
        {
            if (TypeDeterminer.IsNumericType(xType))
            {
                return(FromStringToNumericType(from, defaultVal, xType, out result));
            }
            if (TypeDeterminer.IsGuidType(xType))
            {
                return(FromStringToGuid(from, defaultVal, out result));
            }
            if (TypeDeterminer.IsDateTimeTypes(xType))
            {
                return(FromStringToDateTimeType(from, defaultVal, xType, out result));
            }
            if (TypeDeterminer.IsEnumType(xType))
            {
                return(FromStringToEnum(from, defaultVal, out result));
            }
            if (TypeDeterminer.IsOriginObject(xType))
            {
                result = defaultVal;
                return(true);
            }

            object _ = default(X);

            result = from.Is(typeof(X), t => _ = t) ? _ : defaultVal;
            return(false);
        }
        private static bool FromStringToNullableTypeProxy(string from, Type xType, out object result)
        {
            var innerType = TypeConv.GetNonNullableType(xType);

            if (TypeDeterminer.IsNumericType(innerType))
            {
                return(FromStringToNullableNumericType(from, innerType, out result));
            }
            if (TypeDeterminer.IsGuidType(innerType))
            {
                return(FromStringToNullableGuid(from, out result));
            }
            if (TypeDeterminer.IsDateTimeTypes(innerType))
            {
                return(FromStringToNullableDateTimeType(from, innerType, out result));
            }
            if (TypeDeterminer.IsEnumType(xType))
            {
                return(FromStringToNullableEnum(from, innerType, out result));
            }
            if (TypeDeterminer.IsOriginObject(innerType))
            {
                result = from;
                return(true);
            }

            var _ = TypeDeterminer.GetDefaultValue(xType);

            result = from.Is(xType, t => _ = t) ? _ : null;
            return(false);
        }
        private static bool FromObjToNullableTypeProxy(object fromObj, Type xType, out object result)
        {
            var innerType = TypeConv.GetNonNullableType(xType);

            if (TypeDeterminer.IsStringType(innerType))
            {
                result = StrConvX.ObjectSafeToString(fromObj);
                return(true);
            }

            if (TypeDeterminer.IsNumericType(innerType))
            {
                return(FromObjToNullableNumericType(fromObj, innerType, out result));
            }

            if (TypeDeterminer.IsEnumType(innerType))
            {
                result = EnumConvX.ObjToNullableEnum(fromObj, innerType);
            }

            if (TypeDeterminer.IsDateTimeTypes(innerType))
            {
                return(FromObjToNullableDateTimeType(fromObj, innerType, out result));
            }

            if (TypeDeterminer.IsGuidType(innerType))
            {
                result = GuidConvX.ObjToNullableGuid(fromObj);
                return(true);
            }

            if (TypeDeterminer.IsOriginObject(innerType))
            {
                result = fromObj;
                return(true);
            }

            result = null;
            return(false);
        }
        private static bool FromObjToTypeProxy <X>(object fromObj, X defaultVal, Type xType, out object result)
        {
            if (TypeDeterminer.IsStringType(defaultVal, out var defaultStr))
            {
                result = StrConvX.ObjectSafeToString(fromObj, defaultStr);
                return(true);
            }

            if (TypeDeterminer.IsNumericType(xType))
            {
                return(FromObjToNumericType(fromObj, defaultVal, xType, out result));
            }

            if (TypeDeterminer.IsEnumType(xType))
            {
                result = EnumConvX.ObjToEnum(fromObj, xType, defaultVal);
                return(true);
            }

            if (TypeDeterminer.IsDateTimeTypes(xType))
            {
                return(FromObjToDateTime(fromObj, defaultVal, xType, out result));
            }

            if (defaultVal is Guid defaultGuid)
            {
                result = GuidConvX.ObjToGuid(fromObj, defaultGuid);
                return(true);
            }

            if (TypeDeterminer.IsOriginObject(xType))
            {
                result = defaultVal;
                return(true);
            }

            result = defaultVal;
            return(false);
        }
        public static X To <O, X>(O from, X defaultVal = default, CastingContext context = null, IObjectMapper mapper = null)
        {
            var oType             = typeof(O);
            var xType             = typeof(X);
            var oTypeNullableFlag = Types.IsNullableType(oType);
            var xTypeNullableFlag = Types.IsNullableType(xType);

            context ??= CastingContext.DefaultContext;

            if (xType.IsValueType && defaultVal is null)
            {
                defaultVal = Activator.CreateInstance <X>();
            }

            if (from is null)
            {
                return(defaultVal);
            }

            if (oType == xType)
            {
                return(from.AsOrDefault(defaultVal));
            }

            if (CustomConvertManager.TryGetConvertHandler(oType, xType, out var handler))
            {
                return((handler?.Invoke(from)).As <X>() ?? defaultVal);
            }

            if (from is string strFrom)
            {
                return(FromStringTo(strFrom, xType, xTypeNullableFlag, defaultVal));
            }

            if (from is DateTime dtFrom)
            {
                return(FromDateTimeTo(dtFrom, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (from is bool boolFrom)
            {
                return(FromBooleanTo(boolFrom, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (TypeDeterminer.IsEnumType(oType))
            {
                return(FromEnumTo(oType, from, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (TypeDeterminer.IsNullableNumericType(oType) || Types.IsNumericType(oType))
            {
                return(FromNumericTo(oType, oTypeNullableFlag, from, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (from is Guid guid)
            {
                return(FromGuidTo(guid, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (TypeDeterminer.IsNullableGuidType(oType))
            {
                return(FromNullableGuidTo(from.As <Guid?>(), context, xType, xTypeNullableFlag, defaultVal));
            }

            if (from is IConvertible)
            {
                return(Convert.ChangeType(from, xType).As <X>());
            }

            if (oType == TypeClass.ObjectClazz)
            {
                return(FromObjTo(from, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (xType == TypeClass.ObjectClazz)
            {
                return(from.As <X>());
            }

            if (xType.IsAssignableFrom(oType))
            {
                return(from.As <X>());
            }

            if (mapper != null)
            {
                return(mapper.MapTo <O, X>(from));
            }

            try
            {
                return(from.As <X>());
            }
            catch
            {
                try
                {
                    return(DefaultMapper.Instance.MapTo <O, X>(from));
                }
                catch
                {
                    return(xTypeNullableFlag ? default : defaultVal);
                }
            }
        }
        public static object To(object from, Type sourceType, Type targetType,
                                object defaultVal = default, CastingContext context = null, IObjectMapper mapper = null)
        {
            var oType             = sourceType;
            var xType             = targetType;
            var oTypeNullableFlag = Types.IsNullableType(oType);
            var xTypeNullableFlag = Types.IsNullableType(xType);

            context ??= CastingContext.DefaultContext;

            if (xType.IsValueType && defaultVal is null)
            {
                defaultVal = Activator.CreateInstance(xType);
            }

            if (from is null)
            {
                return(defaultVal);
            }

            if (oType == xType)
            {
                return(from.AsOrDefault(defaultVal));
            }

            if (from is string strFrom)
            {
                return(FromStringTo(strFrom, xType, xTypeNullableFlag, defaultVal));
            }

            if (from is DateTime dtFrom)
            {
                return(FromDateTimeTo(dtFrom, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (from is bool boolFrom)
            {
                return(FromBooleanTo(boolFrom, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (TypeDeterminer.IsEnumType(oType))
            {
                return(FromEnumTo(oType, from, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (TypeDeterminer.IsNullableNumericType(oType) || Types.IsNumericType(oType))
            {
                return(FromNumericTo(oType, oTypeNullableFlag, from, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (from is Guid guid)
            {
                return(FromGuidTo(guid, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (TypeDeterminer.IsNullableGuidType(oType))
            {
                return(FromNullableGuidTo(from.As <Guid?>(), context, xType, xTypeNullableFlag, defaultVal));
            }

            if (from is IConvertible)
            {
                return(Convert.ChangeType(from, xType));
            }

            if (oType == TypeClass.ObjectClazz)
            {
                return(FromObjTo(from, oType, context, xType, xTypeNullableFlag, defaultVal));
            }

            if (xType == TypeClass.ObjectClazz)
            {
                return(Convert.ChangeType(from, xType));
            }

            if (xType.IsAssignableFrom(oType))
            {
                return(from);
            }

            if (mapper != null)
            {
                return(mapper.MapTo(oType, xType, from));
            }

            try
            {
                return(Convert.ChangeType(from, xType, context.FormatProvider).AsOrDefault(defaultVal));
            }
            catch
            {
                try
                {
                    return(DefaultMapper.Instance.MapTo(oType, xType, from));
                }
                catch
                {
                    return(xTypeNullableFlag ? default : defaultVal);
                }
            }
        }