using System; using System.ComponentModel; using System.Globalization; namespace Masuit.Tools; public static class IConvertibleExtensions { public static bool IsNumeric(this Type type) { switch (Type.GetTypeCode(type)) { 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; } } /// /// 类型直转 /// /// /// /// public static T ConvertTo(this IConvertible value) where T : IConvertible { if (value != null) { var type = typeof(T); if (value.GetType() == type) { return (T)value; } if (type.IsNumeric()) { return (T)value.ToType(type, new NumberFormatInfo()); } if (value == DBNull.Value) { return default; } if (type.IsEnum) { return (T)Enum.Parse(type, value.ToString(CultureInfo.InvariantCulture)); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { var underlyingType = Nullable.GetUnderlyingType(type); return (T)(underlyingType!.IsEnum ? Enum.Parse(underlyingType, value.ToString(CultureInfo.CurrentCulture)) : Convert.ChangeType(value, underlyingType)); } TypeConverter converter = TypeDescriptor.GetConverter(value); if (converter != null) { if (converter.CanConvertTo(type)) { return (T)converter.ConvertTo(value, type); } } converter = TypeDescriptor.GetConverter(type); if (converter != null) { if (converter.CanConvertFrom(value.GetType())) { return (T)converter.ConvertFrom(value); } } return (T)Convert.ChangeType(value, type); } return (T)value; } /// /// 类型直转 /// /// /// /// 转换失败的默认值 /// public static T TryConvertTo(this IConvertible value, T defaultValue = default) where T : IConvertible { try { return ConvertTo(value); } catch { return defaultValue; } } /// /// 类型直转 /// /// /// /// 转换失败的默认值 /// public static bool TryConvertTo(this IConvertible value, out T result) where T : IConvertible { try { result = ConvertTo(value); return true; } catch { result = default; return false; } } /// /// 类型直转 /// /// /// 目标类型 /// 转换失败的默认值 /// public static bool TryConvertTo(this IConvertible value, Type type, out object result) { try { result = ConvertTo(value, type); return true; } catch { result = default; return false; } } /// /// 类型直转 /// /// /// 目标类型 /// 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.IsEnum) { return Enum.Parse(type, value.ToString(CultureInfo.InvariantCulture)); } if (type.IsNumeric()) { return value.ToType(type, new NumberFormatInfo()); } 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 converter.ConvertTo(value, type); } } converter = TypeDescriptor.GetConverter(type); if (converter != null) { if (converter.CanConvertFrom(value.GetType())) { return converter.ConvertFrom(value); } } return Convert.ChangeType(value, type); } }