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
{
///
/// 类型属性列表映射表
///
private static readonly ConcurrentDictionary PropertyCache = new();
///
/// 判断类型是否实现某个泛型
///
/// 类型
/// 泛型类型
/// bool
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);
}
///
/// 判断类型是否为Nullable类型
///
/// 要处理的类型
/// 是返回True,不是返回False
public static bool IsNullableType(this Type type)
{
return type != null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
}
///
/// 通过类型转换器获取Nullable类型的基础类型
///
/// 要处理的类型对象
///
public static Type GetUnNullableType(this Type type)
{
if (IsNullableType(type))
{
NullableConverter nullableConverter = new NullableConverter(type);
return nullableConverter.UnderlyingType;
}
return type;
}
#region 公共方法
///
/// 从类型成员获取指定Attribute特性
///
/// Attribute特性类型
/// 类型类型成员
/// 是否从继承中查找
/// 存在返回第一个,不存在返回null
public static T GetAttribute(this MemberInfo memberInfo, bool inherit = true) where T : Attribute
{
var attributes = memberInfo.GetCustomAttributes(typeof(T), inherit);
return attributes.FirstOrDefault() as T;
}
///
/// 把对象类型转换为指定类型
///
///
///
///
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);
}
///
/// 把对象类型转化为指定类型
///
/// 动态类型
/// 要转化的源对象
/// 转化后的指定类型的对象,转化失败引发异常。
public static T CastTo(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;
}
///
/// 把对象类型转化为指定类型,转化失败时返回指定的默认值
///
/// 动态类型
/// 要转化的源对象
/// 转化失败返回的指定默认值
/// 转化后的指定类型对象,转化失败时返回指定的默认值
public static T CastTo(this object value, T defaultValue)
{
try
{
return CastTo(value);
}
catch (Exception)
{
return defaultValue;
}
}
///
/// 判断当前值是否介于指定范围内
///
/// 动态类型
/// 动态类型对象
/// 范围起点
/// 范围终点
/// 是否可等于上限(默认等于)
/// 是否可等于下限(默认等于)
/// 是否介于
public static bool IsBetween(this IComparable 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);
}
///
/// 判断当前值是否介于指定范围内
///
/// 动态类型
/// 动态类型对象
/// 范围小值
/// 范围大值
/// 是否可等于小值(默认等于)
/// 是否可等于大值(默认等于)
public static bool IsInRange(this IComparable 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);
}
///
/// 是否存在于
///
public static bool IsIn(this T value, params T[] source)
{
return source.Contains(value);
}
///
/// 将对象[主要是匿名对象]转换为dynamic
///
public static dynamic ToDynamic(this object value)
{
IDictionary 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
}
}