|
|
using Newtonsoft.Json;
|
|
|
using System.ComponentModel;
|
|
|
using System.Reflection;
|
|
|
|
|
|
namespace DS.Module.Core.Extensions;
|
|
|
|
|
|
public static partial class Extensions
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 判断类型是否为Nullable类型
|
|
|
/// </summary>
|
|
|
/// <param name="type"> 要处理的类型 </param>
|
|
|
/// <returns> 是返回True,不是返回False </returns>
|
|
|
public static bool IsNullableType(this Type type)
|
|
|
{
|
|
|
return ((type != null) && type.IsGenericType) && (type.GetGenericTypeDefinition() == typeof(Nullable<>));
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断当前类型是否可由指定类型派生
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TBaseType"></typeparam>
|
|
|
/// <param name="type"></param>
|
|
|
/// <param name="canAbstract"></param>
|
|
|
/// <returns></returns>
|
|
|
public static bool IsDeriveClassFrom<TBaseType>(this Type type, bool canAbstract = false)
|
|
|
{
|
|
|
return IsDeriveClassFrom(type, typeof(TBaseType), canAbstract);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断当前类型是否可由指定类型派生
|
|
|
/// </summary>
|
|
|
public static bool IsDeriveClassFrom(this Type type, Type baseType, bool canAbstract = false)
|
|
|
{
|
|
|
type.NotNull(nameof(type));
|
|
|
baseType.NotNull(nameof(baseType));
|
|
|
return type.IsClass && (!canAbstract && !type.IsAbstract) && type.IsBaseOn(baseType);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 返回当前类型是否是指定基类的派生类
|
|
|
/// </summary>
|
|
|
/// <param name="type">当前类型</param>
|
|
|
/// <param name="baseType">要判断的基类型</param>
|
|
|
/// <returns></returns>
|
|
|
public static bool IsBaseOn(this Type type, Type baseType)
|
|
|
{
|
|
|
if (baseType.IsGenericTypeDefinition)
|
|
|
{
|
|
|
return baseType.IsGenericAssignableFrom(type);
|
|
|
}
|
|
|
|
|
|
return baseType.IsAssignableFrom(type);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断当前泛型类型是否可由指定类型的实例填充
|
|
|
/// </summary>
|
|
|
/// <param name="genericType">泛型类型</param>
|
|
|
/// <param name="type">指定类型</param>
|
|
|
/// <returns></returns>
|
|
|
public static bool IsGenericAssignableFrom(this Type genericType, Type type)
|
|
|
{
|
|
|
genericType.NotNull(nameof(genericType));
|
|
|
type.NotNull(nameof(type));
|
|
|
|
|
|
if (!genericType.IsGenericType)
|
|
|
{
|
|
|
throw new ArgumentException("该功能只支持泛型类型的调用,非泛型类型可使用 IsAssignableFrom 方法。");
|
|
|
}
|
|
|
|
|
|
List<Type> allOthers = new List<Type> { type };
|
|
|
if (genericType.IsInterface)
|
|
|
{
|
|
|
allOthers.AddRange(type.GetInterfaces());
|
|
|
}
|
|
|
|
|
|
foreach (var other in allOthers)
|
|
|
{
|
|
|
Type cur = other;
|
|
|
while (cur != null)
|
|
|
{
|
|
|
if (cur.IsGenericType)
|
|
|
{
|
|
|
cur = cur.GetGenericTypeDefinition();
|
|
|
}
|
|
|
|
|
|
if (cur.IsSubclassOf(genericType) || cur == genericType)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
cur = cur.BaseType;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通过类型转换器获取Nullable类型的基础类型
|
|
|
/// </summary>
|
|
|
/// <param name="type"> 要处理的类型对象 </param>
|
|
|
/// <returns> </returns>
|
|
|
public static Type GetUnNullableType(this Type type)
|
|
|
{
|
|
|
if (IsNullableType(type))
|
|
|
{
|
|
|
NullableConverter nullableConverter = new NullableConverter(type);
|
|
|
return nullableConverter.UnderlyingType;
|
|
|
}
|
|
|
|
|
|
return type;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 转换为Bool类型
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static bool ObjToBool(this object thisValue)
|
|
|
{
|
|
|
bool reval = false;
|
|
|
if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval))
|
|
|
{
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static int ObjToInt(this object thisValue)
|
|
|
{
|
|
|
int reval = 0;
|
|
|
if (thisValue == null) return 0;
|
|
|
if (thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
|
|
|
{
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <param name="errorValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static int ObjToInt(this object thisValue, int errorValue)
|
|
|
{
|
|
|
int reval = 0;
|
|
|
if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
|
|
|
{
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
return errorValue;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static double ObjToMoney(this object thisValue)
|
|
|
{
|
|
|
double reval = 0;
|
|
|
if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
|
|
|
{
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <param name="errorValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static double ObjToMoney(this object thisValue, double errorValue)
|
|
|
{
|
|
|
double reval = 0;
|
|
|
if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
|
|
|
{
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
return errorValue;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static string ObjToString(this object thisValue)
|
|
|
{
|
|
|
if (thisValue != null) return thisValue.ToString().Trim();
|
|
|
return "";
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static bool IsNotEmptyOrNull(this object thisValue)
|
|
|
{
|
|
|
return ObjToString(thisValue) != "" && ObjToString(thisValue) != "undefined" &&
|
|
|
ObjToString(thisValue) != "null";
|
|
|
}
|
|
|
|
|
|
public static bool IsNullOrEmpty(this object thisValue) => thisValue == null || thisValue == DBNull.Value ||
|
|
|
string.IsNullOrWhiteSpace(thisValue.ToString());
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static Decimal ObjToDecimal(this object thisValue)
|
|
|
{
|
|
|
Decimal reval = 0;
|
|
|
if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
|
|
|
{
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <param name="errorValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static Decimal ObjToDecimal(this object thisValue, decimal errorValue)
|
|
|
{
|
|
|
Decimal reval = 0;
|
|
|
if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
|
|
|
{
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
return errorValue;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static DateTime ObjToDate(this object thisValue)
|
|
|
{
|
|
|
DateTime reval = DateTime.MinValue;
|
|
|
if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))
|
|
|
{
|
|
|
reval = Convert.ToDateTime(thisValue);
|
|
|
}
|
|
|
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <param name="errorValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static DateTime ObjToDate(this object thisValue, DateTime errorValue)
|
|
|
{
|
|
|
DateTime reval = DateTime.MinValue;
|
|
|
if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))
|
|
|
{
|
|
|
return reval;
|
|
|
}
|
|
|
|
|
|
return errorValue;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取当前时间的时间戳
|
|
|
/// </summary>
|
|
|
/// <param name="thisValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public static string DateToTimeStamp(this DateTime thisValue)
|
|
|
{
|
|
|
TimeSpan ts = thisValue - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
|
|
return Convert.ToInt64(ts.TotalSeconds).ToString();
|
|
|
}
|
|
|
|
|
|
public static object ChangeType(this object value, Type type)
|
|
|
{
|
|
|
if (value == null && type.IsGenericType) return Activator.CreateInstance(type);
|
|
|
if (value == null) return null;
|
|
|
if (type == value.GetType()) return value;
|
|
|
if (type.IsEnum)
|
|
|
{
|
|
|
if (value is string)
|
|
|
return Enum.Parse(type, value as string);
|
|
|
else
|
|
|
return Enum.ToObject(type, value);
|
|
|
}
|
|
|
|
|
|
if (!type.IsInterface && type.IsGenericType)
|
|
|
{
|
|
|
Type innerType = type.GetGenericArguments()[0];
|
|
|
object innerValue = ChangeType(value, innerType);
|
|
|
return Activator.CreateInstance(type, new object[] { innerValue });
|
|
|
}
|
|
|
|
|
|
if (value is string && type == typeof(Guid)) return new Guid(value as string);
|
|
|
if (value is string && type == typeof(Version)) return new Version(value as string);
|
|
|
if (!(value is IConvertible)) return value;
|
|
|
return Convert.ChangeType(value, type);
|
|
|
}
|
|
|
|
|
|
public static object ChangeTypeList(this object value, Type type)
|
|
|
{
|
|
|
if (value == null) return default;
|
|
|
|
|
|
var gt = typeof(List<>).MakeGenericType(type);
|
|
|
dynamic lis = Activator.CreateInstance(gt);
|
|
|
|
|
|
var addMethod = gt.GetMethod("Add");
|
|
|
string values = value.ToString();
|
|
|
if (values != null && values.StartsWith("(") && values.EndsWith(")"))
|
|
|
{
|
|
|
string[] splits;
|
|
|
if (values.Contains("\",\""))
|
|
|
{
|
|
|
splits = values.Remove(values.Length - 2, 2)
|
|
|
.Remove(0, 2)
|
|
|
.Split("\",\"");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
splits = values.Remove(0, 1)
|
|
|
.Remove(values.Length - 2, 1)
|
|
|
.Split(",");
|
|
|
}
|
|
|
|
|
|
foreach (var split in splits)
|
|
|
{
|
|
|
var str = split;
|
|
|
if (split.StartsWith("\"") && split.EndsWith("\""))
|
|
|
{
|
|
|
str = split.Remove(0, 1)
|
|
|
.Remove(split.Length - 2, 1);
|
|
|
}
|
|
|
|
|
|
addMethod.Invoke(lis, new object[] { ChangeType(str, type) });
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return lis;
|
|
|
}
|
|
|
|
|
|
public static string ToJson(this object value)
|
|
|
{
|
|
|
return JsonConvert.SerializeObject(value);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断是否IEnumerable、ICollection类型
|
|
|
/// </summary>
|
|
|
/// <param name="type"></param>
|
|
|
/// <returns></returns>
|
|
|
// public static bool IsEnumerable(this Type type)
|
|
|
// {
|
|
|
// return type.IsArray
|
|
|
// || type.GetInterfaces().Any(x => x == typeof(ICollection) || x == typeof(IEnumerable));
|
|
|
// }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 从类型成员获取指定Attribute特性
|
|
|
/// </summary>
|
|
|
/// <typeparam name="T">Attribute特性类型</typeparam>
|
|
|
/// <param name="memberInfo">类型类型成员</param>
|
|
|
/// <param name="inherit">是否从继承中查找</param>
|
|
|
/// <returns>存在返回第一个,不存在返回null</returns>
|
|
|
public static T GetAttribute<T>(this MemberInfo memberInfo, bool inherit = true) where T : Attribute
|
|
|
{
|
|
|
var attributes = memberInfo.GetCustomAttributes(typeof(T), inherit);
|
|
|
return attributes.FirstOrDefault() as T;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 从类型成员获取指定Attribute特性
|
|
|
/// </summary>
|
|
|
/// <param name="type">Attribute特性类型</param>
|
|
|
/// <param name="memberInfo">类型类型成员</param>
|
|
|
/// <param name="inherit">是否从继承中查找</param>
|
|
|
/// <returns>存在返回第一个,不存在返回null</returns>
|
|
|
public static Type GetAttribute(this MemberInfo memberInfo, Type type, bool inherit = true)
|
|
|
{
|
|
|
var attributes = memberInfo.GetCustomAttributes(type, inherit);
|
|
|
return attributes.FirstOrDefault() as Type;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 判断是否实体类型
|
|
|
/// </summary>
|
|
|
/// <param name="type"></param>
|
|
|
/// <returns></returns>
|
|
|
// public static bool IsEntityType(this Type type)
|
|
|
// {
|
|
|
// type.NotNull(nameof(type));
|
|
|
// return typeof(IEntityWithIdentity<>).IsGenericAssignableFrom(type) && !type.IsAbstract && !type.IsInterface;
|
|
|
// }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 转换为Guid类型
|
|
|
/// </summary>
|
|
|
/// <param name="str"></param>
|
|
|
/// <returns></returns>
|
|
|
public static Guid ToGuid(this string str)
|
|
|
{
|
|
|
Guid guid;
|
|
|
if (Guid.TryParse(str, out guid))
|
|
|
{
|
|
|
return guid;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return Guid.Empty;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static string ToDescription(this MemberInfo member)
|
|
|
{
|
|
|
DescriptionAttribute desc = member.GetCustomAttribute<DescriptionAttribute>();
|
|
|
if (!desc.IsNull())
|
|
|
{
|
|
|
return desc.Description;
|
|
|
}
|
|
|
|
|
|
//显示名
|
|
|
DisplayNameAttribute display = member.GetCustomAttribute<DisplayNameAttribute>();
|
|
|
if (!display.IsNull())
|
|
|
{
|
|
|
return display.DisplayName;
|
|
|
}
|
|
|
|
|
|
return member.Name;
|
|
|
}
|
|
|
|
|
|
public static string GetKeySelector(this Type type, string keyName)
|
|
|
{
|
|
|
string[] propertyNames = keyName.Split(".");
|
|
|
return propertyNames.Select(o => type.GetProperty(o)).FirstOrDefault()?.Name;
|
|
|
}
|
|
|
} |