| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 | 
							- using System;
 
- using System.ComponentModel;
 
- using System.Globalization;
 
- using System.Linq;
 
- 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.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));
 
- 			}
 
- 			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 = 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.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="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;
 
- 	}
 
- }
 
 
  |