|
@@ -1,108 +1,211 @@
|
|
|
using System;
|
|
|
+using System.ComponentModel;
|
|
|
using System.Globalization;
|
|
|
|
|
|
-namespace Masuit.Tools
|
|
|
+namespace Masuit.Tools;
|
|
|
+
|
|
|
+public static class IConvertibleExtensions
|
|
|
{
|
|
|
- public static class IConvertibleExtensions
|
|
|
+ public static bool IsNumeric(this Type type)
|
|
|
{
|
|
|
- /// <summary>
|
|
|
- /// 类型直转
|
|
|
- /// </summary>
|
|
|
- /// <typeparam name="T"></typeparam>
|
|
|
- /// <param name="value"></param>
|
|
|
- /// <returns></returns>
|
|
|
-
|
|
|
- public static T ConvertTo<T>(this IConvertible value) where T : IConvertible
|
|
|
+ switch (Type.GetTypeCode(type))
|
|
|
{
|
|
|
- return (T)ConvertTo(value, typeof(T));
|
|
|
+ case TypeCode.Byte:
|
|
|
+ case TypeCode.SByte:
|
|
|
+ case TypeCode.UInt16:
|
|
|
+ case TypeCode.UInt32:
|
|
|
+ case TypeCode.UInt64:
|
|
|
+ case TypeCode.Int16:
|
|
|
+ case TypeCode.Int32:
|
|
|
+ case TypeCode.Int64:
|
|
|
+ case TypeCode.Decimal:
|
|
|
+ case TypeCode.Double:
|
|
|
+ case TypeCode.Single:
|
|
|
+ return true;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 类型直转
|
|
|
- /// </summary>
|
|
|
- /// <typeparam name="T"></typeparam>
|
|
|
- /// <param name="value"></param>
|
|
|
- /// <param name="defaultValue">转换失败的默认值</param>
|
|
|
- /// <returns></returns>
|
|
|
- public static T TryConvertTo<T>(this IConvertible value, T defaultValue = default) where T : IConvertible
|
|
|
+ /// <summary>
|
|
|
+ /// 类型直转
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="T"></typeparam>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+
|
|
|
+ public static T ConvertTo<T>(this IConvertible value) where T : IConvertible
|
|
|
+ {
|
|
|
+ if (value != null)
|
|
|
{
|
|
|
- try
|
|
|
+ var type = typeof(T);
|
|
|
+ if (value.GetType() == type)
|
|
|
{
|
|
|
- return (T)ConvertTo(value, typeof(T));
|
|
|
+ return (T)value;
|
|
|
}
|
|
|
- catch
|
|
|
+
|
|
|
+ if (type.IsNumeric())
|
|
|
{
|
|
|
- return defaultValue;
|
|
|
+ return (T)value.ToType(type, new NumberFormatInfo());
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 类型直转
|
|
|
- /// </summary>
|
|
|
- /// <typeparam name="T"></typeparam>
|
|
|
- /// <param name="value"></param>
|
|
|
- /// <param name="result">转换失败的默认值</param>
|
|
|
- /// <returns></returns>
|
|
|
- public static bool TryConvertTo<T>(this IConvertible value, out T result) where T : IConvertible
|
|
|
- {
|
|
|
- try
|
|
|
+ if (value == DBNull.Value)
|
|
|
{
|
|
|
- result = (T)ConvertTo(value, typeof(T));
|
|
|
- return true;
|
|
|
+ return default;
|
|
|
}
|
|
|
- catch
|
|
|
+
|
|
|
+ if (type.IsEnum)
|
|
|
{
|
|
|
- result = default;
|
|
|
- return false;
|
|
|
+ return (T)Enum.Parse(type, value.ToString(CultureInfo.InvariantCulture));
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 类型直转
|
|
|
- /// </summary>
|
|
|
- /// <param name="value"></param>
|
|
|
- /// <param name="type">目标类型</param>
|
|
|
- /// <param name="result">转换失败的默认值</param>
|
|
|
- /// <returns></returns>
|
|
|
- public static bool TryConvertTo(this IConvertible value, Type type, out object result)
|
|
|
- {
|
|
|
- try
|
|
|
+ if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
|
|
|
{
|
|
|
- result = ConvertTo(value, type);
|
|
|
- return true;
|
|
|
+ var underlyingType = Nullable.GetUnderlyingType(type);
|
|
|
+ return (T)(underlyingType!.IsEnum ? Enum.Parse(underlyingType, value.ToString(CultureInfo.CurrentCulture)) : Convert.ChangeType(value, underlyingType));
|
|
|
}
|
|
|
- catch
|
|
|
+
|
|
|
+ TypeConverter converter = TypeDescriptor.GetConverter(value);
|
|
|
+ if (converter != null)
|
|
|
{
|
|
|
- result = default;
|
|
|
- return false;
|
|
|
+ if (converter.CanConvertTo(type))
|
|
|
+ {
|
|
|
+ return (T)converter.ConvertTo(value, type);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 类型直转
|
|
|
- /// </summary>
|
|
|
- /// <param name="value"></param>
|
|
|
- /// <param name="type">目标类型</param>
|
|
|
- /// <returns></returns>
|
|
|
- public static object ConvertTo(this IConvertible value, Type type)
|
|
|
- {
|
|
|
- if (null == value)
|
|
|
+ converter = TypeDescriptor.GetConverter(type);
|
|
|
+ if (converter != null)
|
|
|
{
|
|
|
- return default;
|
|
|
+ if (converter.CanConvertFrom(value.GetType()))
|
|
|
+ {
|
|
|
+ return (T)converter.ConvertFrom(value);
|
|
|
+ }
|
|
|
}
|
|
|
+ return (T)Convert.ChangeType(value, type);
|
|
|
+ }
|
|
|
|
|
|
- if (type.IsEnum)
|
|
|
+ return (T)value;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 类型直转
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="T"></typeparam>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <param name="defaultValue">转换失败的默认值</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static T TryConvertTo<T>(this IConvertible value, T defaultValue = default) where T : IConvertible
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ return ConvertTo<T>(value);
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ return defaultValue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 类型直转
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="T"></typeparam>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <param name="result">转换失败的默认值</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static bool TryConvertTo<T>(this IConvertible value, out T result) where T : IConvertible
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ result = ConvertTo<T>(value);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ result = default;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 类型直转
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <param name="type">目标类型</param>
|
|
|
+ /// <param name="result">转换失败的默认值</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static bool TryConvertTo(this IConvertible value, Type type, out object result)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ result = ConvertTo(value, type);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ result = default;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 类型直转
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <param name="type">目标类型</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static object ConvertTo(this IConvertible value, Type type)
|
|
|
+ {
|
|
|
+ if (value == null)
|
|
|
+ {
|
|
|
+ return default;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (value.GetType() == type)
|
|
|
+ {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (value == DBNull.Value)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type.IsNumeric())
|
|
|
+ {
|
|
|
+ return value.ToType(type, new NumberFormatInfo());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type.IsEnum)
|
|
|
+ {
|
|
|
+ return Enum.Parse(type, value.ToString(CultureInfo.InvariantCulture));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
|
|
|
+ {
|
|
|
+ var underlyingType = Nullable.GetUnderlyingType(type);
|
|
|
+ return underlyingType!.IsEnum ? Enum.Parse(underlyingType, value.ToString(CultureInfo.CurrentCulture)) : Convert.ChangeType(value, underlyingType);
|
|
|
+ }
|
|
|
+
|
|
|
+ var converter = TypeDescriptor.GetConverter(value);
|
|
|
+ if (converter != null)
|
|
|
+ {
|
|
|
+ if (converter.CanConvertTo(type))
|
|
|
{
|
|
|
- return Enum.Parse(type, value.ToString(CultureInfo.InvariantCulture));
|
|
|
+ return converter.ConvertTo(value, type);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
|
|
|
+ converter = TypeDescriptor.GetConverter(type);
|
|
|
+ if (converter != null)
|
|
|
+ {
|
|
|
+ if (converter.CanConvertFrom(value.GetType()))
|
|
|
{
|
|
|
- var underlyingType = Nullable.GetUnderlyingType(type);
|
|
|
- return underlyingType!.IsEnum ? Enum.Parse(underlyingType, value.ToString(CultureInfo.CurrentCulture)) : Convert.ChangeType(value, underlyingType);
|
|
|
+ return converter.ConvertFrom(value);
|
|
|
}
|
|
|
-
|
|
|
- return Convert.ChangeType(value, type);
|
|
|
}
|
|
|
+
|
|
|
+ return value;
|
|
|
}
|
|
|
}
|