123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- 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;
- }
- }
- /// <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)
- {
- var type = typeof(T);
- if (value.GetType() == type)
- {
- return (T)value;
- }
- if (type.IsEnum)
- {
- return (T)Enum.Parse(type, value.ToString(CultureInfo.InvariantCulture));
- }
- if (value == DBNull.Value)
- {
- return default;
- }
- if (type.IsNumeric())
- {
- return (T)value.ToType(type, new NumberFormatInfo());
- }
- 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));
- }
- var converter = TypeDescriptor.GetConverter(value);
- if (converter.CanConvertTo(type))
- {
- return (T)converter.ConvertTo(value, type);
- }
- converter = TypeDescriptor.GetConverter(type);
- if (converter.CanConvertFrom(value.GetType()))
- {
- return (T)converter.ConvertFrom(value);
- }
- return (T)Convert.ChangeType(value, type);
- }
- 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 = null;
- 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 null;
- }
- if (value.GetType() == type)
- {
- return value;
- }
- if (value == DBNull.Value)
- {
- return null;
- }
- if (type.IsAssignableFrom(typeof(string)))
- {
- return value.ToString();
- }
- if (type.IsEnum)
- {
- return Enum.Parse(type, value.ToString(CultureInfo.InvariantCulture));
- }
- if (type.IsAssignableFrom(typeof(Guid)))
- {
- return Guid.Parse(value.ToString());
- }
- if (type.IsAssignableFrom(typeof(DateTime)))
- {
- return DateTime.Parse(value.ToString());
- }
- if (type.IsAssignableFrom(typeof(DateTimeOffset)))
- {
- return DateTimeOffset.Parse(value.ToString());
- }
- 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.CanConvertTo(type))
- {
- return converter.ConvertTo(value, type);
- }
- converter = TypeDescriptor.GetConverter(type);
- return converter.CanConvertFrom(value.GetType()) ? converter.ConvertFrom(value) : Convert.ChangeType(value, type);
- }
- /// <summary>
- /// 对象类型转换
- /// </summary>
- /// <param name="this">当前值</param>
- /// <returns>转换后的对象</returns>
- public static T ChangeTypeTo<T>(this object @this)
- {
- return (T)ChangeType(@this, typeof(T));
- }
- /// <summary>
- /// 对象类型转换
- /// </summary>
- /// <param name="this">当前值</param>
- /// <param name="defaultValue">默认值</param>
- /// <returns>转换后的对象</returns>
- public static T ChangeTypeTo<T>(this object @this, T defaultValue)
- {
- return @this == null ? defaultValue : (T)ChangeType(@this, typeof(T));
- }
- /// <summary>
- /// 对象类型转换
- /// </summary>
- /// <param name="this">当前值</param>
- /// <param name="type">指定类型的类型</param>
- /// <returns>转换后的对象</returns>
- public static object ChangeType(this object @this, Type type)
- {
- var currType = Nullable.GetUnderlyingType(@this.GetType()) ?? @this.GetType();
- type = Nullable.GetUnderlyingType(type) ?? type;
- if (@this == DBNull.Value)
- {
- if (!type.IsValueType)
- {
- return null;
- }
- throw new Exception("不能将null值转换为" + type.Name + "类型!");
- }
- if (currType == type)
- {
- return @this;
- }
- if (type.IsAssignableFrom(typeof(string)))
- {
- return @this.ToString();
- }
- if (type.IsEnum)
- {
- return Enum.Parse(type, @this.ToString(), true);
- }
- if (type.IsAssignableFrom(typeof(Guid)))
- {
- return Guid.Parse(@this.ToString());
- }
- if (!type.IsArray || !currType.IsArray)
- {
- return Convert.ChangeType(@this, type);
- }
- var length = ((Array)@this).Length;
- var targetType = Type.GetType(type.FullName.Trim('[', ']'));
- var array = Array.CreateInstance(targetType, length);
- for (int j = 0; j < length; j++)
- {
- var tmp = ((Array)@this).GetValue(j);
- array.SetValue(ChangeType(tmp, targetType), j);
- }
- return array;
- }
- }
|