using Apewer; using Apewer.Internals.QrCode; using Apewer.Models; using System; using System.Collections.Generic; using System.Reflection; using System.Text; namespace Apewer { /// <summary>类实用工具。</summary> public class ClassUtility { /// <summary>从外部加载对象。</summary> public static object CreateObject(string path, string type, bool ignoreCase) { try { var a = Assembly.LoadFrom(path); var t = a.GetType(type, false, ignoreCase); if (t != null) { var result = Activator.CreateInstance(t); return result; } } catch { } return null; } /// <summary>解析源对象。</summary> public static Dictionary<string, string> GetOrigin(TextSet instance) { if (instance == null) return null; return instance.Origin; } /// <summary>解析源对象。</summary> public static Dictionary<string, object> GetOrigin(ObjectSet instance) { if (instance == null) return null; return instance.Origin; } /// <summary>解析源对象。</summary> public static Dictionary<string, T> GetOrigin<T>(ObjectSet<T> instance) // where T : ObjectSet<T> { if (instance == null) return null; return instance.Origin; } /// <summary>获取指定的首个特性,特性不存在时返回 Null 值。</summary> public static T GetAttribute<T>(object target) where T : Attribute { if (target == null) return null; try { return GetAttribute<T>(target.GetType()); } catch { return null; } } /// <summary>获取指定的首个特性,特性不存在时返回 Null 值。</summary> public static T GetAttribute<T>(Type target, bool inherit = false) where T : Attribute { if (target == null) return null; try { var type = target; var attributes = type.GetCustomAttributes(typeof(T), inherit); if (attributes.LongLength > 0L) { var attribute = attributes[0] as T; return attribute; } } catch { } return null; } /// <summary>获取指定的首个特性,特性不存在时返回 Null 值。</summary> public static T GetAttribute<T>(PropertyInfo property, bool inherit = false) where T : Attribute { if (property == null) return null; try { var type = property; var attributes = type.GetCustomAttributes(typeof(T), inherit); if (attributes.LongLength > 0L) { var attribute = attributes[0] as T; return attribute; } } catch { } return null; } /// <summary>获取指定的首个特性,特性不存在时返回 Null 值。</summary> public static T GetAttribute<T>(MethodInfo methods, bool inherit = false) where T : Attribute { if (methods == null) return null; try { var type = methods; var attributes = type.GetCustomAttributes(typeof(T), inherit); if (attributes.LongLength > 0L) { var attribute = attributes[0] as T; return attribute; } } catch { } return null; } /// <summary>获取一个值,指示该属性是否 static。</summary> public static bool IsStatic(PropertyInfo property, bool withNonPublic = false) { if (property == null) return false; var getter = property.GetGetMethod(); if (getter != null) return getter.IsStatic; if (withNonPublic) { getter = property.GetGetMethod(true); if (getter != null) return getter.IsStatic; } var setter = property.GetSetMethod(); if (setter != null) return setter.IsStatic; if (withNonPublic) { setter = property.GetSetMethod(true); if (setter != null) return setter.IsStatic; } return false; } /// <summary>调用泛型对象的 ToString() 方法。</summary> public static string ToString<T>(T target) { var type = typeof(T); var methods = type.GetMethods(); foreach (var method in methods) { if (method.Name != "ToString") continue; if (method.GetParameters().LongLength > 0L) continue; var result = (string)method.Invoke(target, null); return result; } return null; } /// <summary>调用方法。</summary> /// <exception cref="ArgumentException"></exception> /// <exception cref="InvalidOperationException"></exception> /// <exception cref="MethodAccessException"></exception> /// <exception cref="NotSupportedException"></exception> /// <exception cref="TargetException"></exception> /// <exception cref="TargetInvocationException"></exception> /// <exception cref="TargetParameterCountException"></exception> public static object InvokeMethod(object instance, MethodInfo method, params object[] parameters) { if (instance == null || method == null) return null; { var pis = method.GetParameters(); if (pis == null || pis.Length < 1) { return method.Invoke(instance, null); } } { if (parameters == null) return method.Invoke(instance, new object[] { null }); return method.Invoke(instance, parameters); } } /// <summary>获取属性值。</summary> /// <exception cref="ArgumentException"></exception> /// <exception cref="InvalidOperationException"></exception> /// <exception cref="MethodAccessException"></exception> /// <exception cref="NotSupportedException"></exception> /// <exception cref="TargetException"></exception> /// <exception cref="TargetInvocationException"></exception> /// <exception cref="TargetParameterCountException"></exception> public static T InvokeGet<T>(object instance, PropertyInfo property) { if (instance == null || property == null || !property.CanRead) return default; #if NET20 || NET40 var getter = property.GetGetMethod(); if (getter != null) { try { var value = getter.Invoke(instance, null); if (value != null) { return (T)value; } } catch { } } return default; #else var value = property.GetValue(instance); try { return (T)value; } catch { return default; } #endif } /// <summary>设置属性值。</summary> /// <exception cref="ArgumentException"></exception> /// <exception cref="InvalidOperationException"></exception> /// <exception cref="MethodAccessException"></exception> /// <exception cref="NotSupportedException"></exception> /// <exception cref="TargetException"></exception> /// <exception cref="TargetInvocationException"></exception> /// <exception cref="TargetParameterCountException"></exception> public static void InvokeSet<T>(object instance, PropertyInfo property, T value) { if (instance == null || property == null || !property.CanWrite) return; #if NET20 || NET40 var setter = property.GetSetMethod(); if (setter != null) { try { setter.Invoke(instance, new object[] { value }); } catch { } } #else property.SetValue(instance, value); #endif } /// <summary>指示方法是否存在于指定类型中。</summary> public static bool ExistIn(MethodInfo method, Type type) { if (method == null) return false; if (type == null) return false; return type.Equals(method.DeclaringType.Equals(type)); } /// <summary>指示方法是否存在于指定类型中。</summary> public static bool ExistIn<T>(MethodInfo method) { if (method == null) return false; var type = typeof(T); return type.Equals(method.DeclaringType.Equals(type)); } /// <summary>判断指定类型可序列化。</summary> public static bool CanSerialize(Type type, bool inherit = false) { if (type == null) return false; var nsas = type.GetCustomAttributes(typeof(NonSerializedAttribute), inherit); if (nsas != null && nsas.Length > 0) return false; var sas = type.GetCustomAttributes(typeof(SerializableAttribute), inherit); if (sas == null || sas.Length < 1) return false; return true; } /// <summary>判断指定类型具有特性。</summary> private static bool ContainsAttribute<T>(object[] attributes) where T : Attribute { if (attributes == null) return false; if (attributes.Length < 1) return false; return true; } /// <summary>判断指定类型具有特性。</summary> public static bool ContainsAttribute<T>(Type type, bool inherit = false) where T : Attribute { return type == null ? false : ContainsAttribute<T>(type.GetCustomAttributes(typeof(T), inherit)); } /// <summary>判断指定属性具有特性。</summary> public static bool ContainsAttribute<T>(PropertyInfo property, bool inherit = false) where T : Attribute { return property == null ? false : ContainsAttribute<T>(property.GetCustomAttributes(typeof(T), inherit)); } /// <summary>判断基类。</summary> public static bool IsInherits(Type child, Type @base) { // 检查参数。 if (child == null || @base == null) return false; // 忽略 System.Object。 var quantum = typeof(object); if (@base.Equals(quantum)) return true; if (child.Equals(quantum)) return true; // 循环判断基类。 var current = child; while (true) { var parent = current.BaseType; if (parent.Equals(@base)) return true; if (parent.Equals(quantum)) break; current = parent; } return false; } /// <summary></summary> public static IEnumerable<Type> GetTypes(Assembly assembly) { if (assembly == null) return null; var types = null as IEnumerable<Type>; if (types == null) { try { types = assembly.GetExportedTypes(); } catch { types = null; } } if (types == null) { try { types = assembly.GetTypes(); } catch { types = null; } } return types; } /// <summary>能从外部创建对象实例。</summary> public static bool CanNewClass<T>() { return CanNewClass(typeof(T)); } /// <summary>能从外部创建对象实例。</summary> public static bool CanNewClass(Type type) { if (type == null) return false; if (!type.IsClass) return false; if (type.IsAbstract) return false; var methods = type.GetMethods(); var constructors = type.GetConstructors(); foreach (var i in constructors) { if (i.IsPublic) { var parameters = i.GetParameters(); if (parameters.Length < 1) { return true; } } } return false; } /// <summary>克隆对象,创建新对象。可指定包含对象的属性和字段。</summary> public static T Clone<T>(T current, T failed = default(T), bool properties = true, bool fields = false) where T : new() { if (current == null) return default(T); var type = typeof(T); var target = new T(); foreach (var property in type.GetProperties()) { var getter = property.GetGetMethod(); var setter = property.GetSetMethod(); if (getter == null || setter == null) continue; var value = getter.Invoke(current, null); setter.Invoke(target, new object[] { value }); } foreach (var field in type.GetFields()) { var value = field.GetValue(current); field.SetValue(target, value); } return target; } /// <summary>对每个属性执行动作。</summary> public static void ForEachProperties(object instance, Action<Property> action, bool withNonPublic = true, bool withStatic = false) { if (instance == null || action == null) return; var type = instance.GetType(); if (type == null) return; var properties = new List<PropertyInfo>(); properties.AddRange(type.GetProperties()); if (withNonPublic) properties.AddRange(type.GetProperties(BindingFlags.NonPublic)); foreach (var info in properties) { var arg = new Property() { Instance = instance, Type = type, Information = info, Getter = info.GetGetMethod(), Setter = info.GetSetMethod() }; if (arg.IsStatic && !withStatic) continue; action.Invoke(arg); } } /// <summary>遍历属性。</summary> public static void ForEachPublicProperties(object instance, Action<PropertyInfo> action) { if (instance != null && action != null) ForEachPublicProperties(instance.GetType(), action); } /// <summary>遍历属性。</summary> public static void ForEachPublicProperties(Type type, Action<PropertyInfo> action) { if (type == null || action == null) return; foreach (var property in type.GetProperties()) action.Invoke(property); } /// <summary>检查类型。</summary> public static bool TypeEquals(object instance, Type type) { if (instance == null) return type == null ? true : false; if (instance is PropertyInfo) { return ((PropertyInfo)instance).PropertyType.Equals(type); } if (instance is MethodInfo) { return ((MethodInfo)instance).ReturnType.Equals(type); } return instance.GetType().Equals(type); } /// <summary>检查类型。</summary> public static bool TypeEquals<T>(object instance) { return TypeEquals(instance, typeof(T)); } /// <summary>安全转换为 List<<typeparamref name="T"/>> 对象。可指定排除 NULL 值元素。</summary> /// <typeparam name="T"></typeparam> public static List<T> ToList<T>(IEnumerable<T> objects, bool excludeNull = false) { var list = new List<T>(); if (objects != null) { foreach (var value in objects) { if (excludeNull && value == null) continue; list.Add(value); } } return list; } /// <summary></summary> public static bool IsEmpty<T>(IEnumerable<T> objects) { if (objects == null) return true; foreach (var i in objects) return false; return true; } /// <summary></summary> public static bool NotEmpty<T>(IEnumerable<T> objects) { if (objects == null) return false; foreach (var i in objects) return true; return false; } /// <summary></summary> public static bool Contains<T>(IEnumerable<T> objects, T cell) { if (objects == null) return false; var a = (object)cell; foreach (var i in objects) { var b = (object)i; if (a == b) return true; } return false; } /// <summary></summary> public static List<T> Sub<T>(IEnumerable<T> objects, long start = 0, long count = -1, Func<T> stuffer = null) { if (count == 0) return new List<T>(); var hasCount = count > 0L; var output = new List<T>(); if (start < 0) { for (var i = start; i < 0; i++) { output.Add(stuffer == null ? default : stuffer()); if (hasCount && output.Count >= count) return output; } } if (objects != null) { var offset = 0L; foreach (var i in objects) { if (offset < start) { offset += 1L; continue; } offset += 1L; output.Add(i); if (hasCount && output.Count >= count) return output; } } while (hasCount && output.Count < count) { output.Add(stuffer == null ? default : stuffer()); } return output; } } }