Files
KJD_WebService/MAX.Core/Helpers/ReflectionHelper.cs
T
chfei fa03add754 增加同步物流模块
修改现有架构,改为分模块( 简易版)
2026-09-22 17:52:42 +08:00

615 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
namespace MAX.Core.Helpers;
/// <summary>
/// 反射操作
/// </summary>
public static class ReflectionHelper
{
/// <summary>
/// 获取类型描述,使用DescriptionAttribute设置描述
/// </summary>
/// <typeparam name="T">类型</typeparam>
public static string GetDescription<T>()
{
return GetDescription(Common.GetType<T>());
}
/// <summary>
/// 获取类型成员描述,使用DescriptionAttribute设置描述
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="memberName">成员名称</param>
public static string GetDescription<T>(string memberName)
{
return GetDescription(Common.GetType<T>(), memberName);
}
/// <summary>
/// 获取类型成员描述,使用DescriptionAttribute设置描述
/// </summary>
/// <param name="type">类型</param>
/// <param name="memberName">成员名称</param>
public static string GetDescription(Type type, string memberName)
{
if (type == null)
{
return string.Empty;
}
if (string.IsNullOrWhiteSpace(memberName))
{
return string.Empty;
}
return GetDescription(type.GetTypeInfo().GetMember(memberName).FirstOrDefault());
}
/// <summary>
/// 获取类型成员描述,使用DescriptionAttribute设置描述
/// </summary>
/// <param name="member">成员</param>
public static string GetDescription(MemberInfo member)
{
if (member == null)
{
return string.Empty;
}
return member.GetCustomAttribute<DescriptionAttribute>() is DescriptionAttribute attribute ? attribute.Description : member.Name;
}
/// <summary>
/// 获取显示名称,使用DisplayNameAttribute设置显示名称
/// </summary>
/// <typeparam name="T">类型</typeparam>
public static string GetDisplayName<T>()
{
return GetDisplayName(Common.GetType<T>());
}
/// <summary>
/// 获取显示名称,使用DisplayAttribute或DisplayNameAttribute设置显示名称
/// </summary>
public static string GetDisplayName(MemberInfo member)
{
if (member == null)
{
return string.Empty;
}
if (member.GetCustomAttribute<DisplayNameAttribute>() is DisplayNameAttribute displayNameAttribute)
{
return displayNameAttribute.DisplayName;
}
return string.Empty;
}
/// <summary>
/// 获取显示名称或描述,使用DisplayNameAttribute设置显示名称,使用DescriptionAttribute设置描述
/// </summary>
/// <typeparam name="T">类型</typeparam>
public static string GetDisplayNameOrDescription<T>()
{
return GetDisplayNameOrDescription(Common.GetType<T>());
}
/// <summary>
/// 获取属性显示名称或描述,使用DisplayAttribute或DisplayNameAttribute设置显示名称,使用DescriptionAttribute设置描述
/// </summary>
public static string GetDisplayNameOrDescription(MemberInfo member)
{
string result = GetDisplayName(member);
return string.IsNullOrWhiteSpace(result) ? GetDescription(member) : result;
}
/// <summary>
/// 查找类型列表
/// </summary>
/// <typeparam name="TFind">查找类型</typeparam>
/// <param name="assemblies">待查找的程序集列表</param>
public static List<Type> FindTypes<TFind>(params Assembly[] assemblies)
{
Type findType = typeof(TFind);
return FindTypes(findType, assemblies);
}
/// <summary>
/// 查找类型列表
/// </summary>
/// <param name="findType">查找类型</param>
/// <param name="assemblies">待查找的程序集列表</param>
public static List<Type> FindTypes(Type findType, params Assembly[] assemblies)
{
List<Type> result = [];
foreach (Assembly assembly in assemblies)
{
result.AddRange(GetTypes(findType, assembly));
}
return result.Distinct().ToList();
}
/// <summary>
/// 获取类型列表
/// </summary>
private static List<Type> GetTypes(Type findType, Assembly assembly)
{
List<Type> result = [];
if (assembly == null)
{
return result;
}
Type[] types;
try
{
types = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
Debug.WriteLine(ex);
return result;
}
foreach (Type type in types)
{
AddType(result, findType, type);
}
return result;
}
/// <summary>
/// 添加类型
/// </summary>
private static void AddType(List<Type> result, Type findType, Type type)
{
if (type.IsInterface || type.IsAbstract)
{
return;
}
if (findType.IsAssignableFrom(type) == false && MatchGeneric(findType, type) == false)
{
return;
}
result.Add(type);
}
/// <summary>
/// 泛型匹配
/// </summary>
private static bool MatchGeneric(Type findType, Type type)
{
if (findType.IsGenericTypeDefinition == false)
{
return false;
}
Type definition = findType.GetGenericTypeDefinition();
foreach (Type implementedInterface in type.FindInterfaces((filter, criteria) => true, null))
{
if (implementedInterface.IsGenericType == false)
{
continue;
}
return definition.IsAssignableFrom(implementedInterface.GetGenericTypeDefinition());
}
return false;
}
/// <summary>
/// 获取实现了接口的所有实例
/// </summary>
/// <typeparam name="TInterface">接口类型</typeparam>
/// <param name="assemblies">待查找的程序集列表</param>
public static List<TInterface> GetInstancesByInterface<TInterface>(params Assembly[] assemblies)
{
return FindTypes<TInterface>(assemblies)
.Select(t => CreateInstance<TInterface>(t)).ToList();
}
/// <summary>
/// 动态创建实例
/// </summary>
/// <typeparam name="T">目标类型</typeparam>
/// <param name="type">类型</param>
/// <param name="parameters">传递给构造函数的参数</param>
public static T CreateInstance<T>(Type type, params object[] parameters)
{
return Convert.To<T>(Activator.CreateInstance(type, parameters));
}
public static Type GetType(string typeName)
{
Type type = null;
Assembly[] assemblyArray = AppDomain.CurrentDomain.GetAssemblies();
int assemblyArrayLength = assemblyArray.Length;
for (int i = 0; i < assemblyArrayLength; ++i)
{
type = assemblyArray[i].GetType(typeName);
if (type != null)
{
return type;
}
}
for (int i = 0; i < assemblyArrayLength; ++i)
{
Type[] typeArray = assemblyArray[i].GetTypes();
int typeArrayLength = typeArray.Length;
for (int j = 0; j < typeArrayLength; ++j)
{
if (typeArray[j].Name.Equals(typeName))
{
return typeArray[j];
}
}
}
return type;
}
/// <summary>
/// 获取程序集
/// </summary>
/// <param name="assemblyName">程序集名称</param>
public static Assembly GetAssembly(string assemblyName)
{
return Assembly.Load(new AssemblyName(assemblyName));
}
/// <summary>
/// 是否布尔类型
/// </summary>
/// <param name="member">成员</param>
public static bool IsBool(MemberInfo member)
{
if (member == null)
{
return false;
}
return member.MemberType switch
{
MemberTypes.TypeInfo => member.ToString() == "System.Boolean",
MemberTypes.Property => IsBool((PropertyInfo)member),
_ => false,
};
}
/// <summary>
/// 是否布尔类型
/// </summary>
private static bool IsBool(PropertyInfo property)
{
return property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?);
}
/// <summary>
/// 是否枚举类型
/// </summary>
/// <param name="member">成员</param>
public static bool IsEnum(MemberInfo member)
{
if (member == null)
{
return false;
}
return member.MemberType switch
{
MemberTypes.TypeInfo => ((TypeInfo)member).IsEnum,
MemberTypes.Property => IsEnum((PropertyInfo)member),
_ => false,
};
}
/// <summary>
/// 是否枚举类型
/// </summary>
private static bool IsEnum(PropertyInfo property)
{
if (property.PropertyType.GetTypeInfo().IsEnum)
{
return true;
}
Type value = Nullable.GetUnderlyingType(property.PropertyType);
if (value == null)
{
return false;
}
return value.GetTypeInfo().IsEnum;
}
/// <summary>
/// 是否日期类型
/// </summary>
/// <param name="member">成员</param>
public static bool IsDate(MemberInfo member)
{
if (member == null)
{
return false;
}
return member.MemberType switch
{
MemberTypes.TypeInfo => member.ToString() == "System.DateTime",
MemberTypes.Property => IsDate((PropertyInfo)member),
_ => false,
};
}
/// <summary>
/// 是否日期类型
/// </summary>
private static bool IsDate(PropertyInfo property)
{
if (property.PropertyType == typeof(DateTime))
{
return true;
}
if (property.PropertyType == typeof(DateTime?))
{
return true;
}
return false;
}
/// <summary>
/// 是否整型
/// </summary>
/// <param name="member">成员</param>
public static bool IsInt(MemberInfo member)
{
if (member == null)
{
return false;
}
return member.MemberType switch
{
MemberTypes.TypeInfo => member.ToString() is "System.Int32" or "System.Int16" or "System.Int64",
MemberTypes.Property => IsInt((PropertyInfo)member),
_ => false,
};
}
/// <summary>
/// 是否整型
/// </summary>
private static bool IsInt(PropertyInfo property)
{
if (property.PropertyType == typeof(int))
{
return true;
}
if (property.PropertyType == typeof(int?))
{
return true;
}
if (property.PropertyType == typeof(short))
{
return true;
}
if (property.PropertyType == typeof(short?))
{
return true;
}
if (property.PropertyType == typeof(long))
{
return true;
}
if (property.PropertyType == typeof(long?))
{
return true;
}
return false;
}
/// <summary>
/// 是否数值类型
/// </summary>
/// <param name="member">成员</param>
public static bool IsNumber(MemberInfo member)
{
if (member == null)
{
return false;
}
if (IsInt(member))
{
return true;
}
return member.MemberType switch
{
MemberTypes.TypeInfo => member.ToString() is "System.Double" or "System.Decimal" or "System.Single",
MemberTypes.Property => IsNumber((PropertyInfo)member),
_ => false,
};
}
/// <summary>
/// 是否数值类型
/// </summary>
private static bool IsNumber(PropertyInfo property)
{
if (property.PropertyType == typeof(double))
{
return true;
}
if (property.PropertyType == typeof(double?))
{
return true;
}
if (property.PropertyType == typeof(decimal))
{
return true;
}
if (property.PropertyType == typeof(decimal?))
{
return true;
}
if (property.PropertyType == typeof(float))
{
return true;
}
if (property.PropertyType == typeof(float?))
{
return true;
}
return false;
}
/// <summary>
/// 是否集合
/// </summary>
/// <param name="type">类型</param>
public static bool IsCollection(Type type)
{
if (type.IsArray)
{
return true;
}
return IsGenericCollection(type);
}
/// <summary>
/// 是否泛型集合
/// </summary>
/// <param name="type">类型</param>
public static bool IsGenericCollection(Type type)
{
if (!type.IsGenericType)
{
return false;
}
Type typeDefinition = type.GetGenericTypeDefinition();
return typeDefinition == typeof(IEnumerable<>)
|| typeDefinition == typeof(IReadOnlyCollection<>)
|| typeDefinition == typeof(IReadOnlyList<>)
|| typeDefinition == typeof(ICollection<>)
|| typeDefinition == typeof(IList<>)
|| typeDefinition == typeof(List<>);
}
/// <summary>
/// 从目录中获取所有程序集
/// </summary>
/// <param name="directoryPath">目录绝对路径</param>
public static List<Assembly> GetAssemblies(string directoryPath)
{
return Directory.GetFiles(directoryPath, "*.*", SearchOption.AllDirectories).ToList()
.Where(t => t.EndsWith(".exe") || t.EndsWith(".dll"))
.Select(path => Assembly.Load(new AssemblyName(path))).ToList();
}
/// <summary>
/// 获取公共属性列表
/// </summary>
/// <param name="instance">实例</param>
public static List<CommonItem> GetPublicProperties(object instance)
{
PropertyInfo[] properties = instance.GetType().GetProperties();
return properties.ToList().Select(t => new CommonItem(t.Name, t.GetValue(instance))).ToList();
}
/// <summary>
/// 获取顶级基类
/// </summary>
/// <typeparam name="T">类型</typeparam>
public static Type GetTopBaseType<T>()
{
return GetTopBaseType(typeof(T));
}
/// <summary>
/// 获取顶级基类
/// </summary>
/// <param name="type">类型</param>
public static Type GetTopBaseType(Type type)
{
if (type == null)
{
return null;
}
if (type.IsInterface)
{
return type;
}
if (type.BaseType == typeof(object))
{
return type;
}
return GetTopBaseType(type.BaseType);
}
/// <summary>
/// 获取元素类型,如果是集合,返回集合的元素类型
/// </summary>
/// <param name="type">类型</param>
public static Type GetElementType(Type type)
{
if (IsCollection(type) == false)
{
return type;
}
if (type.IsArray)
{
return type.GetElementType();
}
Type[] genericArgumentsTypes = type.GetTypeInfo().GetGenericArguments();
if (genericArgumentsTypes == null || genericArgumentsTypes.Length == 0)
{
throw new ArgumentException("泛型类型参数不能为空");
}
return genericArgumentsTypes[0];
}
}