You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

612 lines
21 KiB

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&lt;<typeparamref name="T"/>&gt; 对象。可指定排除 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 Equals<T>(T a, T b) => EqualityComparer<T>.Default.Equals(a, b);
/// <summary>确定集合是否包含特定值</summary>
public static bool Contains<T>(IEnumerable<T> objects, T cell)
{
if (objects == null) return false;
// 以 Object 类型对比。
// var a = (object)cell;
// foreach (var i in objects)
// {
// var b = (object)i;
// if (a == b) return true;
// }
// return false;
// objects 实现了含有 Contains 方法的接口。
if (objects is ICollection<T>) return ((ICollection<T>)objects).Contains(cell);
// cell 无效。
if (cell == null)
{
foreach (var i in objects)
{
if (i == null) return true;
}
return false;
}
// cell 有效,进行默认比较。
var comparer = EqualityComparer<T>.Default;
foreach (var i in objects)
{
if (comparer.Equals(i, cell)) return true;
}
return false;
}
/// <summary>获取集合中元素的数量。</summary>
public static int Count<T>(IEnumerable<T> objects)
{
if (objects == null) return 0;
// objects 实现了含有 Contains 方法的接口。
if (objects is ICollection<T>) return ((ICollection<T>)objects).Count;
var count = 0;
foreach (var cell in objects) count++;
return count;
}
/// <summary>对元素去重,且去除 NULL 值。</summary>
public static T[] Distinct<T>(IEnumerable<T> items)
{
if (items == null) throw new ArgumentNullException(nameof(items));
var count = Count(items);
var added = 0;
var array = new T[count];
var comparer = EqualityComparer<T>.Default;
foreach (var item in items)
{
if (item == null) continue;
var contains = false;
foreach (var i in array)
{
if (comparer.Equals(i, item))
{
contains = true;
break;
}
}
if (contains) continue;
array[added] = item;
added++;
}
if (added < count)
{
var temp = new T[added];
Array.Copy(array, 0, temp, 0, added);
array = temp;
}
return array;
}
/// <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;
}
}
}