static DateInfo() { // to register DateInfo ConvertHandler and Checker into CustomConvertManager CustomConvertManager.RegisterOrOverride( TypeClass.StringClazz, typeof(DateInfo), StringConvBeHandler, StringConvToHandler); }
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); } } }
/// <summary> /// Determine whether the given string can be of the given type. <br /> /// 判断给定的字符串是否能成为给定的类型。 /// </summary> /// <param name="text"></param> /// <param name="type"></param> /// <param name="matchedCallback"></param> /// <param name="context"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> public static bool Is(this string text, Type type, CastingContext context, Action <object> matchedCallback = null) { if (type is null) { throw new ArgumentNullException(nameof(type)); } if (context is null) { throw new ArgumentNullException(nameof(context)); } if (Types.IsNullableType(type)) { return(text is null || Is(text, TypeConv.GetNonNullableType(type), context, matchedCallback)); } if (!__unsupportedTypeCheck(type, out var typeIsAssignableFromEncoding, out var typeCanBeChecking, out var checkingHandler)) { return(false); } if (typeCanBeChecking) { return(__customChecking(checkingHandler)); } return(TypeIs.__enumIs(text, type, matchedCallback, context.IgnoreCase) .Or(() => TypeIs.__charIs(text, type, matchedCallback)) .Or(() => TypeIs.__numericIs(text, type, matchedCallback, context.NumberStyles, context.FormatProvider)) .Or(() => TypeIs.__booleanIs(text, type, matchedCallback)) .Or(() => TypeIs.__dateTimeIs(text, type, matchedCallback, context.Format, context.DateTimeStyles, context.FormatProvider)) .Or(() => TypeIs.__dateTimeOffsetIs(text, type, matchedCallback, context.Format, context.DateTimeStyles, context.FormatProvider)) .Or(() => TypeIs.__timeSpanIs(text, type, matchedCallback, context.Format, context.FormatProvider)) .Or(() => TypeIs.__guidIs(text, type, matchedCallback, context.Format)) .Or(() => TypeIs.__versionIs(text, type, matchedCallback)) .Or(() => TypeIs.__ipAddressIs(text, type, matchedCallback)) .Or(() => TypeIs.__encodingIs(text, matchedCallback, typeIsAssignableFromEncoding))); // ReSharper disable once InconsistentNaming bool __unsupportedTypeCheck(Type t, out bool encodingFlag, out bool checkingFlag, out Func <object, bool> checker) { encodingFlag = t == typeof(Encoding) || TypeReflections.IsTypeDerivedFrom(t, typeof(Encoding), TypeDerivedOptions.CanAbstract); checkingFlag = CustomConvertManager.TryGetChecker(TypeClass.StringClazz, t, out checker); return(t.IsValueType .Or(encodingFlag) .Or(checkingFlag) .Or(() => t == typeof(Version)) .Or(() => t == typeof(IPAddress))); } // ReSharper disable once InconsistentNaming bool __customChecking(Func <object, bool> handler) { var result = handler?.Invoke(text) ?? false; result.IfTrue(matchedCallback, text); return(result); } }