|
|
|
|
using System;
|
|
|
|
|
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>
|
|
|
|
|
/// 判断是否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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="thisValue"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string ObjToString(this object thisValue)
|
|
|
|
|
{
|
|
|
|
|
if (thisValue != null) return thisValue.ToString().Trim();
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|