222 lines
8.5 KiB
C#
222 lines
8.5 KiB
C#
using NewLife.Serialization;
|
||
using Newtonsoft.Json;
|
||
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Collections.Generic;
|
||
using System.Dynamic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using System.Runtime.Serialization.Formatters.Binary;
|
||
using System.Text;
|
||
using System.Text.Json;
|
||
using System.Text.RegularExpressions;
|
||
using System.Threading.Tasks;
|
||
using System.Xml;
|
||
|
||
namespace YY.Admin.Core.Extension
|
||
{
|
||
public static partial class ObjectExtension
|
||
{
|
||
/// <summary>
|
||
/// 类型属性列表映射表
|
||
/// </summary>
|
||
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> PropertyCache = new();
|
||
|
||
/// <summary>
|
||
/// 判断类型是否实现某个泛型
|
||
/// </summary>
|
||
/// <param name="type">类型</param>
|
||
/// <param name="generic">泛型类型</param>
|
||
/// <returns>bool</returns>
|
||
public static bool HasImplementedRawGeneric(this Type type, Type generic)
|
||
{
|
||
// 检查接口类型
|
||
var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType);
|
||
if (isTheRawGenericType) return true;
|
||
|
||
// 检查类型
|
||
while (type != null && type != typeof(object))
|
||
{
|
||
isTheRawGenericType = IsTheRawGenericType(type);
|
||
if (isTheRawGenericType) return true;
|
||
type = type.BaseType;
|
||
}
|
||
|
||
return false;
|
||
|
||
// 判断逻辑
|
||
bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type);
|
||
}
|
||
/// <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>
|
||
/// 通过类型转换器获取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;
|
||
}
|
||
#region 公共方法
|
||
/// <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>
|
||
/// 把对象类型转换为指定类型
|
||
/// </summary>
|
||
/// <param name="value"></param>
|
||
/// <param name="conversionType"></param>
|
||
/// <returns></returns>
|
||
public static object CastTo(this object value, Type conversionType)
|
||
{
|
||
if (value == null)
|
||
{
|
||
return null;
|
||
}
|
||
if (conversionType.IsNullableType())
|
||
{
|
||
conversionType = conversionType.GetUnNullableType();
|
||
}
|
||
if (conversionType.IsEnum)
|
||
{
|
||
return Enum.Parse(conversionType, value.ToString());
|
||
}
|
||
if (conversionType == typeof(Guid))
|
||
{
|
||
return Guid.Parse(value.ToString());
|
||
}
|
||
|
||
if (conversionType == typeof(string)) return value.ToString();
|
||
if (value.GetType() == typeof(JsonElement)) return Convert.ChangeType(value?.ToString(), conversionType);
|
||
return Convert.ChangeType(value, conversionType);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 把对象类型转化为指定类型
|
||
/// </summary>
|
||
/// <typeparam name="T"> 动态类型 </typeparam>
|
||
/// <param name="value"> 要转化的源对象 </param>
|
||
/// <returns> 转化后的指定类型的对象,转化失败引发异常。 </returns>
|
||
public static T CastTo<T>(this object value)
|
||
{
|
||
if (value == null || default(T) == null)
|
||
{
|
||
return default;
|
||
}
|
||
if (value.GetType() == typeof(T))
|
||
{
|
||
return (T)value;
|
||
}
|
||
object result = CastTo(value, typeof(T));
|
||
return (T)result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 把对象类型转化为指定类型,转化失败时返回指定的默认值
|
||
/// </summary>
|
||
/// <typeparam name="T"> 动态类型 </typeparam>
|
||
/// <param name="value"> 要转化的源对象 </param>
|
||
/// <param name="defaultValue"> 转化失败返回的指定默认值 </param>
|
||
/// <returns> 转化后的指定类型对象,转化失败时返回指定的默认值 </returns>
|
||
public static T CastTo<T>(this object value, T defaultValue)
|
||
{
|
||
try
|
||
{
|
||
return CastTo<T>(value);
|
||
}
|
||
catch (Exception)
|
||
{
|
||
return defaultValue;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断当前值是否介于指定范围内
|
||
/// </summary>
|
||
/// <typeparam name="T"> 动态类型 </typeparam>
|
||
/// <param name="value"> 动态类型对象 </param>
|
||
/// <param name="start"> 范围起点 </param>
|
||
/// <param name="end"> 范围终点 </param>
|
||
/// <param name="leftEqual"> 是否可等于上限(默认等于) </param>
|
||
/// <param name="rightEqual"> 是否可等于下限(默认等于) </param>
|
||
/// <returns> 是否介于 </returns>
|
||
public static bool IsBetween<T>(this IComparable<T> value, T start, T end, bool leftEqual = true, bool rightEqual = true) where T : IComparable
|
||
{
|
||
bool flag = leftEqual ? value.CompareTo(start) >= 0 : value.CompareTo(start) > 0;
|
||
return flag && (rightEqual ? value.CompareTo(end) <= 0 : value.CompareTo(end) < 0);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断当前值是否介于指定范围内
|
||
/// </summary>
|
||
/// <typeparam name="T"> 动态类型 </typeparam>
|
||
/// <param name="value"> 动态类型对象 </param>
|
||
/// <param name="min">范围小值</param>
|
||
/// <param name="max">范围大值</param>
|
||
/// <param name="minEqual">是否可等于小值(默认等于)</param>
|
||
/// <param name="maxEqual">是否可等于大值(默认等于)</param>
|
||
public static bool IsInRange<T>(this IComparable<T> value, T min, T max, bool minEqual = true, bool maxEqual = true) where T : IComparable
|
||
{
|
||
bool flag = minEqual ? value.CompareTo(min) >= 0 : value.CompareTo(min) > 0;
|
||
return flag && (maxEqual ? value.CompareTo(max) <= 0 : value.CompareTo(max) < 0);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否存在于
|
||
/// </summary>
|
||
public static bool IsIn<T>(this T value, params T[] source)
|
||
{
|
||
return source.Contains(value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将对象[主要是匿名对象]转换为dynamic
|
||
/// </summary>
|
||
public static dynamic ToDynamic(this object value)
|
||
{
|
||
IDictionary<string, object> expando = new ExpandoObject();
|
||
Type type = value.GetType();
|
||
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(type);
|
||
foreach (PropertyDescriptor property in properties)
|
||
{
|
||
var val = property.GetValue(value);
|
||
if (property.PropertyType.FullName != null && property.PropertyType.FullName.StartsWith("<>f__AnonymousType"))
|
||
{
|
||
dynamic dval = val.ToDynamic();
|
||
expando.Add(property.Name, dval);
|
||
}
|
||
else
|
||
{
|
||
expando.Add(property.Name, val);
|
||
}
|
||
}
|
||
return (ExpandoObject)expando;
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
}
|