using System; using System.Collections.Generic; using System.Text; using System.Reflection; using System.Collections; using CommonLang.Log; namespace CommonLang.Property { public static class PropertyUtil { private static Logger s_log; public static Logger log { get { if (s_log == null) { s_log = LoggerFactory.GetLogger(typeof(PropertyUtil).Name); } return s_log; } } static public FieldInfo[] SortFields(FieldInfo[] fields) { Array.Sort(fields, BaseFieldSorter); return fields; } static public PropertyInfo[] SortProperties(PropertyInfo[] properties) { Array.Sort(properties, BasePropertySorter); return properties; } static public IComparer BaseFieldSorter = new FieldSorter(); static public IComparer BasePropertySorter = new PropertySorter(); public class FieldSorter : IComparer { public int Compare(FieldInfo x, FieldInfo y) { return x.Name.CompareTo(y.Name); } } public class PropertySorter : IComparer { public int Compare(PropertyInfo x, PropertyInfo y) { return x.Name.CompareTo(y.Name); } } public static Attribute GetAttributeByType(FieldInfo field, Type attributeType) { object[] cas = field.GetCustomAttributes(attributeType, false); if (cas != null && cas.Length > 0) { return cas[0] as Attribute; } return null; } public static T GetAttribute(Type type) where T : System.Attribute { while (!type.Equals(typeof(object))) { object[] cas = type.GetCustomAttributes(typeof(T), false); if (cas != null && cas.Length > 0) { return (T)cas[0]; } else if (type.BaseType != null) { type = type.BaseType; } else { return null; } } return null; } public static T GetAttribute(MemberInfo member) where T : System.Attribute { object[] cas = member.GetCustomAttributes(typeof(T), false); if (cas != null && cas.Length > 0) { return (T)cas[0]; } return null; } public static T GetAttribute(FieldInfo field) where T : System.Attribute { object[] cas = field.GetCustomAttributes(typeof(T), false); if (cas != null && cas.Length > 0) { return (T)cas[0]; } return null; } public static T GetAttribute(PropertyInfo property) where T : System.Attribute { object[] cas = property.GetCustomAttributes(typeof(T), false); if (cas != null && cas.Length > 0) { return (T)cas[0]; } return null; } static public T GetEnumAttribute(object value) where T : Attribute { Type type = value.GetType(); string name = Enum.GetName(type, value); if (name == null) { return null; } FieldInfo field = type.GetField(name); if (field != null) { return GetAttribute(field); } return null; } public static DescAttribute GetDesc(Type type) { return GetAttribute(type); } public static DescAttribute GetDesc(MemberInfo field) { return GetAttribute(field); } public static ListAttribute GetListDesc(MemberInfo field) { return GetAttribute(field); } /// /// 将一个对象里面所有的Attribute的标记的Field值,全部取出 /// /// /// /// /// static public void CollectFieldTypeValues(object data, List collection) { if (data != null) { Type fieldType = typeof(T); Type type = data.GetType(); if (data is T) { collection.Add((T)data); } if (type.IsClass && !type.IsPrimitive) { if (data is IDictionary) { IDictionary map = data as IDictionary; foreach (object o in map.Values) { CollectFieldTypeValues(o, collection); } } else if (data is ICollection) { ICollection list = data as ICollection; foreach (object o in list) { CollectFieldTypeValues(o, collection); } } else if (type.IsArray) { Array array = (Array)data; foreach (object o in array) { CollectFieldTypeValues(o, collection); } } else { foreach (FieldInfo field in type.GetFields()) { if (!field.IsStatic) { object fd = field.GetValue(data); if (fd != null) { CollectFieldTypeValues(fd, collection); } } } } } } } /// /// 将一个对象里面所有的Attribute的标记的Field值,全部取出 /// /// /// /// static public void CollectFieldAttributeValues(object data, Type attributeType, List collection) { if (data != null) { Type type = data.GetType(); if (data is IDictionary) { IDictionary map = data as IDictionary; foreach (object o in map.Values) { CollectFieldAttributeValues(o, attributeType, collection); } } else if (data is ICollection) { ICollection list = data as ICollection; foreach (object o in list) { CollectFieldAttributeValues(o, attributeType, collection); } } else if (type.IsArray) { Array array = (Array)data; foreach (object o in array) { CollectFieldAttributeValues(o, attributeType, collection); } } else if (type.IsClass) { foreach (FieldInfo field in type.GetFields()) { if (!field.IsStatic) { object fd = field.GetValue(data); if (fd != null) { Attribute attr = PropertyUtil.GetAttributeByType(field, attributeType); if (attr != null) { FieldAttributeValue fv = new FieldAttributeValue(field, attr, fd, data); collection.Add(fv); } else { CollectFieldAttributeValues(fd, attributeType, collection); } } } } } } } static public void CollectFieldAttributeValuesGeneric(object data, List> collection) where A : Attribute { List list = new List(); CollectFieldAttributeValues(data, typeof(A), list); foreach (FieldAttributeValue fv in list) { collection.Add(new TFieldAttributeValue(fv.Field, fv.AttributeData as A, fv.FieldValue, fv.FieldOwner)); } } /// /// 返回书写习惯的类型字符串 /// /// /// public static string ToTypeDefineString(Type type) { if (type.IsGenericType) { StringBuilder sb = new StringBuilder(); int tidx = type.Name.IndexOf('`'); if (tidx > 0) { sb.Append(type.Name.Substring(0, tidx)); } else { sb.Append(type.Name); } sb.Append("<"); Type[] g_args = type.GetGenericArguments(); foreach (Type g_arg in g_args) { sb.Append(ToTypeDefineString(g_arg)); if (!g_arg.Equals(g_args[g_args.Length - 1])) { sb.Append(", "); } } sb.Append(">"); return sb.ToString(); } return type.Name; } public static T GetFieldOrPropertyOrMethodValue(object componentData, string fieldName) { Type componentType = componentData.GetType(); FieldInfo depend_field = componentType.GetField(fieldName); if (depend_field != null) { try { T ret = (T)depend_field.GetValue(componentData); return ret; } catch (Exception err) { log.Error(err.Message, err); } } PropertyInfo depend_property = componentType.GetProperty(fieldName); if (depend_property != null) { try { T ret = (T)depend_property.GetValue(componentData, null); return ret; } catch (Exception err) { log.Error(err.Message, err); } } MethodInfo depend_method = componentType.GetMethod(fieldName); if (depend_method != null) { try { T ret = (T)depend_method.Invoke(componentData, ZERO_ARGS); return ret; } catch (Exception err) { log.Error(err.Message, err); } } return default(T); } public readonly static object[] ZERO_ARGS = new object[] { }; public static void SetMemberValue(MemberInfo field, object obj, object value) { if (field is FieldInfo) { (field as FieldInfo).SetValue(obj, value); } else if (field is PropertyInfo) { var set = (field as PropertyInfo).GetSetMethod(); if (set != null) { set.Invoke(obj, new object[] { value }); } } } public static object GetMemberValue(MemberInfo field, object obj) { if (field is FieldInfo) { return (field as FieldInfo).GetValue(obj); } else if (field is PropertyInfo) { var get = (field as PropertyInfo).GetGetMethod(); if (get != null) { return get.Invoke(obj, ZERO_ARGS); } } return null; } } public struct FieldAttributeValue { public Attribute AttributeData; public FieldInfo Field; public object FieldOwner; public object FieldValue; public FieldAttributeValue(FieldInfo field, Attribute attr, object fieldData, object fieldOwner) { this.AttributeData = attr; this.Field = field; this.FieldOwner = fieldOwner; this.FieldValue = fieldData; } } public struct TFieldAttributeValue where A : Attribute { public A AttributeData; public FieldInfo Field; public object FieldOwner; public T FieldValue; public TFieldAttributeValue(FieldInfo field, A attr, object fieldData, object fieldOwner) { this.AttributeData = attr; this.Field = field; this.FieldOwner = fieldOwner; this.FieldValue = (T)fieldData; } } public class TypeDescAttribute : IComparable { public DescAttribute Desc; public Type DataType; public TypeDescAttribute(Type type) { DataType = type; Desc = PropertyUtil.GetAttribute(type); } public override string ToString() { return Desc.Desc; } public int CompareTo(TypeDescAttribute other) { return this.ToString().CompareTo(other.ToString()); } /// /// 如果此类型有DescAttribute签名,则返回Desc /// /// /// public static string GetDescText(Type type) { DescAttribute desc = PropertyUtil.GetAttribute(type); if (desc != null) { return desc.Desc; } return ""; } /// /// 如果此类型有DescAttribute签名,则返回Catgory /// /// /// public static string GetCatgoryName(Type type) { DescAttribute desc = PropertyUtil.GetAttribute(type); if (desc != null) { return desc.Category; } return ""; } } public class MemberDescAttribute : IComparable { public readonly DescAttribute Desc; public readonly MemberInfo DataField; public readonly Type FieldType; public MemberDescAttribute(MemberInfo field) { DataField = field; Desc = PropertyUtil.GetAttribute(field); if (field is FieldInfo) { FieldType = (field as FieldInfo).FieldType; } else if (field is PropertyInfo) { FieldType = (field as PropertyInfo).PropertyType; } else if (field is MethodInfo) { FieldType = (field as MethodInfo).ReturnType; } else { throw new Exception("Error MemberDescAttribute : " + field); } } public string ToDescString() { return (Desc != null ? string.Format("[{0}]", Desc.Desc) : ""); } public override string ToString() { if (DataField is MethodInfo) { return string.Format("{0}() {1}", DataField.Name, ToDescString()); } else { return string.Format("{0} {1}", DataField.Name, ToDescString()); } } public int CompareTo(MemberDescAttribute other) { return DataField.Name.CompareTo(other.DataField.Name); } public object GetValue(object owner) { try { if (DataField is FieldInfo) { FieldInfo field = DataField as FieldInfo; return field.GetValue(owner); } else if (DataField is PropertyInfo) { PropertyInfo field = DataField as PropertyInfo; return field.GetGetMethod().Invoke(owner, new object[0]); } else if (DataField is MethodInfo) { MethodInfo method = DataField as MethodInfo; return method.Invoke(owner, new object[0]); } } catch (Exception err) { PropertyUtil.log.Error(err.Message, err); } return null; } public void SetValue(object owner, object value) { try { if (DataField is FieldInfo) { FieldInfo field = DataField as FieldInfo; field.SetValue(owner, value); } else if (DataField is PropertyInfo) { PropertyInfo field = DataField as PropertyInfo; field.GetSetMethod().Invoke(owner, new object[] { value }); } else if (DataField is MethodInfo) { MethodInfo method = DataField as MethodInfo; method.Invoke(owner, new object[] { value }); } } catch (Exception err) { PropertyUtil.log.Error(err.Message, err); } } } }