587 lines
12 KiB
C#
587 lines
12 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设置显示名称,使用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)
|
|
{
|
|
return GetDescription(member);
|
|
}
|
|
|
|
/// <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];
|
|
}
|
|
}
|