C#反射Helper
//反射 操作 public static class Reflection { #region GetDescription(获取类型描述) /// <summary> /// 获取类型描述,使用<see cref="DescriptionAttribute"/>设置描述 /// </summary> /// <typeparam name="T">类型</typeparam> public static string GetDescription<T>() => GetDescription(Common.GetType<T>()); /// <summary> /// 获取类型成员描述,使用<see cref="DescriptionAttribute"/>设置描述 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="memberName">成员名称</param> public static string GetDescription<T>(string memberName) => GetDescription(Common.GetType<T>(), memberName); /// <summary> /// 获取类型成员描述,使用<see cref="DescriptionAttribute"/>设置描述 /// </summary> /// <param name="type">类型</param> /// <param name="memberName">成员名称</param> public static string GetDescription(Type type, string memberName) { if (type == null) return string.Empty; return memberName.IsEmpty() ? string.Empty : GetDescription(type.GetTypeInfo().GetMember(memberName).FirstOrDefault()); } /// <summary> /// 获取类型成员描述,使用<see cref="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; } #endregion #region GetDisplayName(获取类型显示名称) /// <summary> /// 获取类型显示名称,使用<see cref="DisplayNameAttribute"/>设置显示名称 /// </summary> /// <typeparam name="T">类型</typeparam> /// <returns></returns> public static string GetDisplayName<T>() => GetDisplayName(Common.GetType<T>()); /// <summary> /// 获取类型成员显示名称,,使用<see cref="DisplayNameAttribute"/>或<see cref="DisplayAttribute"/>设置显示名称 /// </summary> /// <param name="member">成员</param> /// <returns></returns> private static string GetDisplayName(MemberInfo member) { if (member == null) return string.Empty; if (member.GetCustomAttribute<DisplayAttribute>() is DisplayAttribute displayAttribute) return displayAttribute.Description; if (member.GetCustomAttribute<DisplayNameAttribute>() is DisplayNameAttribute displayNameAttribute) return displayNameAttribute.DisplayName; return string.Empty; } #endregion #region GetDisplayNameOrDescription(获取显示名称或类型描述) /// <summary> /// 获取类型显示名称或描述,使用<see cref="DescriptionAttribute"/>设置描述,使用<see cref="DisplayNameAttribute"/>设置显示名称 /// </summary> /// <typeparam name="T">类型</typeparam> /// <returns></returns> public static string GetDisplayNameOrDescription<T>() { return GetDisplayNameOrDescription(Common.GetType<T>()); } /// <summary> /// 获取类型显示名称或成员描述,使用<see cref="DescriptionAttribute"/>设置描述,使用<see cref="DisplayNameAttribute"/>或<see cref="DisplayAttribute"/>设置显示名称 /// </summary> /// <param name="member">成员</param> /// <returns></returns> public static string GetDisplayNameOrDescription(MemberInfo member) { var result = GetDisplayName(member); return string.IsNullOrWhiteSpace(result) ? GetDescription(member) : result; } #endregion #region FindTypes(查找类型列表) /// <summary> /// 查找类型列表 /// </summary> /// <typeparam name="TFind">查找类型</typeparam> /// <param name="assemblies">待查找的程序集列表</param> /// <returns></returns> public static List<Type> FindType<TFind>(params Assembly[] assemblies) { var findType = typeof(TFind); return FindTypes(findType, assemblies); } /// <summary> /// 查找类型列表 /// </summary> /// <param name="findType">查找类型</param> /// <param name="assemblies">待查找的程序集列表</param> /// <returns></returns> public static List<Type> FindTypes(Type findType, params Assembly[] assemblies) { var result = new List<Type>(); foreach (var assembly in assemblies) { result.AddRange(GetTypes(findType, assembly)); } return result.Distinct().ToList(); } /// <summary> /// 获取类型列表 /// </summary> /// <param name="findType">查找类型</param> /// <param name="assembly">待查找的程序集</param> /// <returns></returns> private static List<Type> GetTypes(Type findType, Assembly assembly) { var result = new List<Type>(); if (assembly == null) return result; Type[] types; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException) { return result; } foreach (var type in types) AddType(result, findType, type); return result; } /// <summary> /// 添加类型 /// </summary> /// <param name="result">类型列表</param> /// <param name="findType">查找类型</param> /// <param name="type">类型</param> 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> /// <param name="findType">查找类型</param> /// <param name="type">类型</param> /// <returns></returns> private static bool MatchGeneric(Type findType, Type type) { if (findType.IsGenericTypeDefinition == false) return false; var definition = findType.GetGenericTypeDefinition(); foreach (var implementedInterface in type.FindInterfaces((filiter, criteria) => true, null)) { if (implementedInterface.IsGenericType == false) continue; return definition.IsAssignableFrom(implementedInterface.GetGenericTypeDefinition()); } return false; } #endregion #region GetInstancesByInterface(获取实现了接口的所有实例) /// <summary> /// 获取实现了接口的所有实例 /// </summary> /// <typeparam name="TInterface">接口类型</typeparam> /// <param name="assembly">在该程序集中查找</param> public static List<TInterface> GetInstancesByInterface<TInterface>(Assembly assembly) { var typeInterface = typeof(TInterface); return assembly.GetTypes() .Where( t => typeInterface.GetTypeInfo().IsAssignableFrom(t) && t != typeInterface && t.GetTypeInfo().IsAbstract == false) .Select(t => CreateInstance<TInterface>(t)) .ToList(); } #endregion #region CreateInstance(动态创建实例) /// <summary> /// 动态创建实例 /// </summary> /// <typeparam name="T">目标类型</typeparam> /// <param name="type">类型</param> /// <param name="parameters">传递给构造函数的参数</param> public static T CreateInstance<T>(Type type, params object[] parameters) => Conv.To<T>(Activator.CreateInstance(type, parameters)); /// <summary> /// 动态创建实例 /// </summary> /// <typeparam name="T">目标类型</typeparam> /// <param name="className">类名,包括命名空间,如果类型不处于当前执行程序集中,需要包含程序集名,范例:Test.Core.Test2,Test.Core</param> /// <param name="parameters">传递给构造函数的参数</param> public static T CreateInstance<T>(string className, params object[] parameters) { var type = Type.GetType(className) ?? Assembly.GetCallingAssembly().GetType(className); return CreateInstance<T>(type, parameters); } #endregion #region GetAssembly(获取程序集) /// <summary> /// 获取程序集 /// </summary> /// <param name="assemblyName">程序集名称</param> /// <returns></returns> public static Assembly GetAssembly(string assemblyName) => Assembly.Load(new AssemblyName(assemblyName)); #endregion #region GetAssemblies(从目录获取所有程序集) /// <summary> /// 从目录获取所有程序集 /// </summary> /// <param name="directoryPath">目录绝对路径</param> /// <returns></returns> 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(); } #endregion #region GetCurrentAssemblyName(获取当前程序集名称) /// <summary> /// 获取当前程序集名称 /// </summary> public static string GetCurrentAssemblyName() => Assembly.GetCallingAssembly().GetName().Name; #endregion #region GetAttribute(获取特性信息) /// <summary> /// 获取特性信息 /// </summary> /// <typeparam name="TAttribute">泛型特性</typeparam> /// <param name="memberInfo">元数据</param> public static TAttribute GetAttribute<TAttribute>(MemberInfo memberInfo) where TAttribute : Attribute { return (TAttribute)memberInfo.GetCustomAttributes(typeof(TAttribute), false).FirstOrDefault(); } #endregion #region GetAttributes(获取特性信息数据) /// <summary> /// 获取特性信息数组 /// </summary> /// <typeparam name="TAttribute">泛型特性</typeparam> /// <param name="memberInfo">元数据</param> /// <returns></returns> public static TAttribute[] GetAttributes<TAttribute>(MemberInfo memberInfo) where TAttribute : Attribute { return Array.ConvertAll(memberInfo.GetCustomAttributes(typeof(TAttribute), false), x => (TAttribute)x); } #endregion #region GetPropertyInfo(获取属性信息) /// <summary> /// 获取属性信息 /// </summary> /// <param name="type">类型</param> /// <param name="propertyName">属性名</param> /// <returns>存在时返回PropertyInfo,不存在时返回null</returns> public static PropertyInfo GetPropertyInfo(Type type, string propertyName) => type.GetProperties().FirstOrDefault(p => p.Name.Equals(propertyName)); #endregion #region IsBool(是否布尔类型) /// <summary> /// 是否布尔类型 /// </summary> /// <param name="member">成员</param> /// <returns></returns> public static bool IsBool(MemberInfo member) { if (member == null) return false; switch (member.MemberType) { case MemberTypes.TypeInfo: return member.ToString() == "System.Boolean"; case MemberTypes.Property: return IsBool((PropertyInfo)member); } return false; } /// <summary> /// 是否布尔类型 /// </summary> /// <param name="property">属性</param> /// <returns></returns> public static bool IsBool(PropertyInfo property) { return property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?); } #endregion #region IsEnum(是否枚举类型) /// <summary> /// 是否枚举类型 /// </summary> /// <param name="member">成员</param> /// <returns></returns> public static bool IsEnum(MemberInfo member) { if (member == null) { return false; } switch (member.MemberType) { case MemberTypes.TypeInfo: return ((TypeInfo)member).IsEnum; case MemberTypes.Property: return IsEnum((PropertyInfo)member); } return false; } /// <summary> /// 是否枚举类型 /// </summary> /// <param name="property">属性</param> /// <returns></returns> public static bool IsEnum(PropertyInfo property) { if (property.PropertyType.GetTypeInfo().IsEnum) { return true; } var value = Nullable.GetUnderlyingType(property.PropertyType); if (value == null) { return false; } return value.GetTypeInfo().IsEnum; } #endregion #region IsDate(是否日期类型) /// <summary> /// 是否日期类型 /// </summary> /// <param name="member">成员</param> /// <returns></returns> public static bool IsDate(MemberInfo member) { if (member == null) { return false; } switch (member.MemberType) { case MemberTypes.TypeInfo: return member.ToString() == "System.DateTime"; case MemberTypes.Property: return IsDate((PropertyInfo)member); } return false; } /// <summary> /// 是否日期类型 /// </summary> /// <param name="property">属性</param> /// <returns></returns> public static bool IsDate(PropertyInfo property) { if (property.PropertyType == typeof(DateTime)) { return true; } if (property.PropertyType == typeof(DateTime?)) { return true; } return false; } #endregion #region IsInt(是否整型) /// <summary> /// 是否整型 /// </summary> /// <param name="member">成员</param> /// <returns></returns> public static bool IsInt(MemberInfo member) { if (member == null) { return false; } switch (member.MemberType) { case MemberTypes.TypeInfo: return member.ToString() == "System.Int32" || member.ToString() == "System.Int16" || member.ToString() == "System.Int64"; case MemberTypes.Property: return IsInt((PropertyInfo)member); } return false; } /// <summary> /// 是否整型 /// </summary> /// <param name="property">成员</param> /// <returns></returns> public 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; } #endregion #region IsNumber(是否数值类型) /// <summary> /// 是否数值类型 /// </summary> /// <param name="member">成员</param> /// <returns></returns> public static bool IsNumber(MemberInfo member) { if (member == null) { return false; } if (IsInt(member)) { return true; } switch (member.MemberType) { case MemberTypes.TypeInfo: return member.ToString() == "System.Double" || member.ToString() == "System.Decimal" || member.ToString() == "System.Single"; case MemberTypes.Property: return IsNumber((PropertyInfo)member); } return false; } /// <summary> /// 是否数值类型 /// </summary> /// <param name="property">属性</param> /// <returns></returns> public 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; } #endregion #region IsCollection(是否集合) /// <summary> /// 是否集合 /// </summary> /// <param name="type">类型</param> public static bool IsCollection(Type type) => type.IsArray || IsGenericCollection(type); #endregion #region IsGenericCollection(是否泛型集合) /// <summary> /// 是否泛型集合 /// </summary> /// <param name="type">类型</param> public static bool IsGenericCollection(Type type) { if (!type.IsGenericType) return false; var typeDefinition = type.GetGenericTypeDefinition(); return typeDefinition == typeof(IEnumerable<>) || typeDefinition == typeof(IReadOnlyCollection<>) || typeDefinition == typeof(IReadOnlyList<>) || typeDefinition == typeof(ICollection<>) || typeDefinition == typeof(IList<>) || typeDefinition == typeof(List<>); } #endregion #region GetPublicProperties(获取公共属性列表) /// <summary> /// 获取公共属性列表 /// </summary> /// <param name="instance">实例</param> public static List<Item> GetPublicProperties(object instance) { var properties = instance.GetType().GetProperties(); return properties.ToList().Select(t => new Item(t.Name, t.GetValue(instance))).ToList(); } #endregion #region GetTopBaseType(获取顶级基类) /// <summary> /// 获取顶级基类 /// </summary> /// <typeparam name="T">类型</typeparam> /// <returns></returns> public static Type GetTopBaseType<T>() { return GetTopBaseType(typeof(T)); } /// <summary> /// 获取顶级基类 /// </summary> /// <param name="type">类型</param> /// <returns></returns> 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); } #endregion #region IsGenericAssignableFrom(判断当前泛型类型是否可由指定类型的实例填充) /// <summary> /// 判断当前泛型类型是否可由指定类型的实例填充 /// </summary> /// <param name="genericType">泛型类型</param> /// <param name="type">指定类型</param> public static bool IsGenericAssignableFrom(Type genericType, Type type) { Check.NotNull(genericType, nameof(genericType)); Check.NotNull(type, nameof(type)); if (!genericType.IsGenericType) { throw new ArgumentException("该功能只支持泛型类型的调用,非泛型类型可使用 IsAssignableFrom 方法。"); } var allOthers = new List<Type>() { type }; if (genericType.IsInterface) { allOthers.AddRange(type.GetInterfaces()); } foreach (var other in allOthers) { var cur = other; while (cur != null) { if (cur.IsGenericType) { cur = cur.GetGenericTypeDefinition(); } if (cur.IsSubclassOf(genericType) || cur == genericType) { return true; } cur = cur.BaseType; } } return false; } #endregion #region GetElementType(获取元素类型) /// <summary> /// 获取元素类型。如果是集合,返回集合的元素类型 /// </summary> /// <param name="type">类型</param> public static Type GetElementType(Type type) { if (IsCollection(type) == false) return type; if (type.IsArray) return type.GetElementType(); var genericArgumentsTypes = type.GetTypeInfo().GetGenericArguments(); if (genericArgumentsTypes == null || genericArgumentsTypes.Length == 0) throw new ArgumentException("泛型类型参数不能为空"); return genericArgumentsTypes[0]; } #endregion }
#region IsEmpty(是否为空) /// <summary> /// 判断 字符串 是否为空、null或空白字符串 /// </summary> /// <param name="value">数据</param> public static bool IsEmpty(this string value) => string.IsNullOrWhiteSpace(value); #endregion #region SafeString(安全转换为字符串) /// <summary> /// 安全转换为字符串,去除两端空格,当值为null时返回"" /// </summary> /// <param name="input">输入值</param> public static string SafeString(this object input) => input == null ? string.Empty : input.ToString().Trim(); #endregion