using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; namespace Common.Utils; /// /// 属性访问器(用于缓存,提高反射性能) /// /// 类型 internal class PropertyAccessor { public Func? Getter { get; set; } public Action? Setter { get; set; } public PropertyInfo PropertyInfo { get; set; } public PropertyAccessor(PropertyInfo propertyInfo) { PropertyInfo = propertyInfo; } } /// /// 反射工具类 /// 提供类型扫描、属性访问、特性读取等功能,并通过缓存提高性能 /// public static class ReflectionHelper { // 属性访问器缓存 private static readonly ConcurrentDictionary> PropertyAccessorCache = new(); // 特性缓存 private static readonly ConcurrentDictionary AttributeCache = new(); // 类型缓描 private static readonly ConcurrentDictionary TypeCache = new(); #region 类型扫描 /// /// 从程序集中获取所有类型 /// /// 程序集 /// 是否使用缓存(默认 true) /// 类型数组 public static Type[] GetTypes(Assembly assembly, bool useCache = true) { if (useCache && TypeCache.TryGetValue(assembly, out var cachedTypes)) return cachedTypes; var types = assembly.GetTypes(); if (useCache) TypeCache.TryAdd(assembly, types); return types; } /// /// 从当前程序集中查找指定基类的所有子类 /// /// 基类类型 /// 是否包含抽象类(默认 false) /// 子类类型列表 public static List FindSubclassesOf(bool includeAbstract = false) { return FindSubclassesOf(typeof(TBase), includeAbstract); } /// /// 从当前程序集中查找指定基类的所有子类 /// public static List FindSubclassesOf(Type baseType, bool includeAbstract = false) { var assembly = Assembly.GetCallingAssembly(); return GetTypes(assembly) .Where(t => t.IsClass && baseType.IsAssignableFrom(t) && t != baseType) .Where(t => includeAbstract || !t.IsAbstract) .ToList(); } /// /// 从指定程序集中查找实现指定接口的所有类型 /// /// 接口类型 /// 程序集 /// 是否包含抽象类(默认 false) /// 实现类型列表 public static List FindImplementationsOf(Assembly assembly, bool includeAbstract = false) { var interfaceType = typeof(TInterface); return GetTypes(assembly) .Where(t => t.IsClass && interfaceType.IsAssignableFrom(t) && t != interfaceType) .Where(t => includeAbstract || !t.IsAbstract) .ToList(); } /// /// 查找带有指定特性的所有类型 /// /// 特性类型 /// 程序集 /// 是否搜索继承链(默认 true) /// 类型列表 public static List FindTypesWithAttribute(Assembly assembly, bool inherit = true) where TAttribute : Attribute { return GetTypes(assembly) .Where(t => t.GetCustomAttribute(inherit) != null) .ToList(); } #endregion #region 属性访问(高性能) /// /// 获取属性值(使用缓存的访问器,比直接反射快) /// public static object? GetPropertyValue(T obj, string propertyName) { var accessor = GetPropertyAccessor(propertyName); return accessor?.Getter?.Invoke(obj); } /// /// 设置属性值(使用缓存的访问器) /// public static void SetPropertyValue(T obj, string propertyName, object? value) { var accessor = GetPropertyAccessor(propertyName); accessor?.Setter?.Invoke(obj, value); } /// /// 获取属性访问器(内部使用表达式树生成,首次慢,后续快) /// private static PropertyAccessor? GetPropertyAccessor(string propertyName) { var type = typeof(T); var cache = PropertyAccessorCache.GetOrAdd(type, _ => new Dictionary()); lock (cache) { if (cache.TryGetValue(propertyName, out var cachedAccessor)) return (PropertyAccessor)cachedAccessor; var propertyInfo = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); if (propertyInfo == null) return null; var accessor = new PropertyAccessor(propertyInfo); // 使用表达式树生成 Getter if (propertyInfo.CanRead) { var instance = Expression.Parameter(type, "instance"); var property = Expression.Property(instance, propertyInfo); var convert = Expression.Convert(property, typeof(object)); accessor.Getter = Expression.Lambda>(convert, instance).Compile(); } // 使用表达式树生成 Setter if (propertyInfo.CanWrite) { var instance = Expression.Parameter(type, "instance"); var value = Expression.Parameter(typeof(object), "value"); var convert = Expression.Convert(value, propertyInfo.PropertyType); var property = Expression.Property(instance, propertyInfo); var assign = Expression.Assign(property, convert); accessor.Setter = Expression.Lambda>(assign, instance, value).Compile(); } cache[propertyName] = accessor; return accessor; } } /// /// 获取所有属性名称 /// public static List GetPropertyNames(BindingFlags flags = BindingFlags.Public | BindingFlags.Instance) { return typeof(T).GetProperties(flags).Select(p => p.Name).ToList(); } /// /// 获取所有属性信息 /// public static PropertyInfo[] GetProperties(BindingFlags flags = BindingFlags.Public | BindingFlags.Instance) { return typeof(T).GetProperties(flags); } #endregion #region 特性读取(带缓存) /// /// 获取类型的特性(带缓存) /// public static TAttribute? GetAttribute(Type type, bool inherit = true) where TAttribute : Attribute { var attributes = GetAttributes(type, inherit); return attributes.FirstOrDefault(); } /// /// 获取类型的所有指定特性(带缓存) /// public static TAttribute[] GetAttributes(Type type, bool inherit = true) where TAttribute : Attribute { var cached = AttributeCache.GetOrAdd(type, _ => type.GetCustomAttributes(inherit).ToArray()); return cached.OfType().ToArray(); } /// /// 获取成员的特性(带缓存) /// public static TAttribute? GetAttribute(MemberInfo member, bool inherit = true) where TAttribute : Attribute { var attributes = GetAttributes(member, inherit); return attributes.FirstOrDefault(); } /// /// 获取成员的所有指定特性(带缓存) /// public static TAttribute[] GetAttributes(MemberInfo member, bool inherit = true) where TAttribute : Attribute { var cached = AttributeCache.GetOrAdd(member, _ => member.GetCustomAttributes(inherit).ToArray()); return cached.OfType().ToArray(); } /// /// 判断类型是否有指定特性 /// public static bool HasAttribute(Type type, bool inherit = true) where TAttribute : Attribute { return GetAttribute(type, inherit) != null; } /// /// 判断成员是否有指定特性 /// public static bool HasAttribute(MemberInfo member, bool inherit = true) where TAttribute : Attribute { return GetAttribute(member, inherit) != null; } #endregion #region 创建实例 /// /// 创建类型实例(使用无参构造函数) /// public static T? CreateInstance() where T : class { return Activator.CreateInstance(); } /// /// 创建类型实例(使用无参构造函数) /// public static object? CreateInstance(Type type) { return Activator.CreateInstance(type); } /// /// 创建类型实例(使用有参构造函数) /// public static object? CreateInstance(Type type, params object[] args) { return Activator.CreateInstance(type, args); } /// /// 尝试创建类型实例 /// public static bool TryCreateInstance(out T? instance) where T : class { try { instance = CreateInstance(); return instance != null; } catch { instance = null; return false; } } #endregion #region 属性复制 /// /// 将源对象的属性值复制到目标对象(同名属性) /// /// 源类型 /// 目标类型 /// 源对象 /// 目标对象 /// 是否忽略属性名大小写(默认 false) public static void CopyProperties(TSource source, TTarget target, bool ignoreCase = false) { if (source == null || target == null) return; var sourceType = typeof(TSource); var targetType = typeof(TTarget); var sourceProperties = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.CanRead) .ToList(); var targetProperties = targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.CanWrite) .ToDictionary( p => p.Name, p => p, ignoreCase ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal ); foreach (var sourceProp in sourceProperties) if (targetProperties.TryGetValue(sourceProp.Name, out var targetProp)) // 检查类型是否兼容 if (targetProp.PropertyType.IsAssignableFrom(sourceProp.PropertyType)) { var value = sourceProp.GetValue(source); targetProp.SetValue(target, value); } } /// /// 创建目标类型实例并复制属性 /// public static TTarget? MapTo(TSource source, bool ignoreCase = false) where TTarget : class, new() { if (source == null) return null; var target = new TTarget(); CopyProperties(source, target, ignoreCase); return target; } #endregion #region 方法调用 /// /// 调用对象的方法 /// /// 对象实例 /// 方法名 /// 参数 /// 方法返回值 public static object? InvokeMethod(object obj, string methodName, params object[] parameters) { var type = obj.GetType(); var method = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance); if (method == null) throw new InvalidOperationException($"Method '{methodName}' not found on type '{type.FullName}'"); return method.Invoke(obj, parameters); } /// /// 调用静态方法 /// public static object? InvokeStaticMethod(Type type, string methodName, params object[] parameters) { var method = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static); if (method == null) throw new InvalidOperationException($"Static method '{methodName}' not found on type '{type.FullName}'"); return method.Invoke(null, parameters); } #endregion #region 类型判断 /// /// 判断类型是否为可空类型 /// public static bool IsNullableType(Type type) { return Nullable.GetUnderlyingType(type) != null; } /// /// 获取可空类型的基础类型 /// public static Type GetUnderlyingType(Type type) { return Nullable.GetUnderlyingType(type) ?? type; } /// /// 判断类型是否为值类型 /// public static bool IsValueType(Type type) { return type.IsValueType; } /// /// 判断类型是否为引用类型 /// public static bool IsReferenceType(Type type) { return !type.IsValueType; } /// /// 判断类型是否为数字类型 /// public static bool IsNumericType(Type type) { type = GetUnderlyingType(type); return type == typeof(byte) || type == typeof(sbyte) || type == typeof(short) || type == typeof(ushort) || type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong) || type == typeof(float) || type == typeof(double) || type == typeof(decimal); } /// /// 判断类型是否为集合类型 /// public static bool IsCollectionType(Type type) { return type.IsArray || (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) || type.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>)); } #endregion #region 泛型操作 /// /// 判断类型是否为泛型类型 /// public static bool IsGenericType(Type type) { return type.IsGenericType; } /// /// 获取泛型参数类型 /// public static Type[] GetGenericArguments(Type type) { return type.GetGenericArguments(); } /// /// 构造泛型类型(例如:List<> + int => List) /// public static Type MakeGenericType(Type genericTypeDefinition, params Type[] typeArguments) { return genericTypeDefinition.MakeGenericType(typeArguments); } #endregion #region 缓存管理 /// /// 清除所有缓存 /// public static void ClearCache() { PropertyAccessorCache.Clear(); AttributeCache.Clear(); TypeCache.Clear(); } /// /// 清除属性访问器缓存 /// public static void ClearPropertyAccessorCache() { PropertyAccessorCache.Clear(); } /// /// 清除特性缓存 /// public static void ClearAttributeCache() { AttributeCache.Clear(); } /// /// 清除类型缓存 /// public static void ClearTypeCache() { TypeCache.Clear(); } #endregion }