using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections.Concurrent; using System.Reflection; using System.Linq.Expressions; using NaiBa.Util.Extension; namespace NaiBa.Util.Helper { public class ReflectionHelper { private static ConcurrentDictionary dictCache = new ConcurrentDictionary(); #region 得到类里面的属性集合 public static PropertyInfo[] GetProperties(Type type, string[] columns = null) { PropertyInfo[] properties = null; if (dictCache.ContainsKey(type.FullName)) { properties = dictCache[type.FullName] as PropertyInfo[]; } else { properties = type.GetProperties(); dictCache.TryAdd(type.FullName, properties); } if (columns != null && columns.Length > 0) { // 按columns顺序返回属性 var columnPropertyList = new List(); foreach (var column in columns) { var columnProperty = properties.Where(p => p.Name == column).FirstOrDefault(); if (columnProperty != null) { columnPropertyList.Add(columnProperty); } } return columnPropertyList.ToArray(); } else { return properties; } } #endregion public static List GetMembers(Type type) { var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; var members = new List(); members.AddRange(type.GetProperties(flags)); members.AddRange(type.GetFields(flags)); return members; } public static void SetObjectPropertyValue(string propertyName, object value) { var type = typeof(T); var field = type.GetProperty(propertyName); if (field != null) { field.SetValue(null, value); } } public static void SetObjectPropertyValue(object obj, string propertyName, object value) { if (obj != null) { PropertyInfo propertyInfo = GetProperties(obj.GetType()).Where(p => p.Name == propertyName).FirstOrDefault(); // make sure object has the property we are after if (propertyInfo != null) { switch (propertyInfo.PropertyType.FullName) { case "System.Int32": propertyInfo.SetValue(obj, value.ParseToInt(), null); break; case "System.Int64": propertyInfo.SetValue(obj, value.ParseToLong(), null); break; case "System.Decimal": propertyInfo.SetValue(obj, value.ParseToDecimal(), null); break; case "System.Double": propertyInfo.SetValue(obj, value.ParseToDouble(), null); break; default: if (propertyInfo.PropertyType.GenericTypeArguments.Length > 0) { switch (propertyInfo.PropertyType.GenericTypeArguments[0].FullName) { case "System.DateTime": if (!string.IsNullOrEmpty(value.ParseToString())) { propertyInfo.SetValue(obj, value.ParseToString().ParseToDateTime(), null); } break; case "System.Decimal": propertyInfo.SetValue(obj, value.ParseToDecimal(), null); break; } } else { propertyInfo.SetValue(obj, value, null); } break; } } } } public static object GetObjectPropertyValue(object obj, string propertyName) { if (obj != null) { PropertyInfo propertyInfo = GetProperties(obj.GetType()).Where(p => p.Name == propertyName).FirstOrDefault(); // make sure object has the property we are after if (propertyInfo != null) { return propertyInfo.GetValue(obj); } } return null; } public static string GetGenericName(Type type) { if (type.GetGenericArguments().Length > 0) { return GetGenericName(type.GetGenericArguments().FirstOrDefault()); } else { if (type.GetGenericArguments().FirstOrDefault() != null) { return type.GetGenericArguments().FirstOrDefault().Name; } else { return type.Name; } } } public static string GetMemberName(Expression> memberExpression) { MemberExpression expressionBody = (MemberExpression)memberExpression.Body; return expressionBody.Member.Name; } public static void SetObjectValue(ref T obj, MemberInfo member, object value) { // Boxing method used for modifying structures var boxed = obj.GetType().IsValueType ? (object)obj : obj; SetMemberValue(ref boxed, member, value); obj = (T)boxed; } public static void SetMemberValue(ref T obj, MemberInfo member, object value) { if (IsProperty(member)) { var prop = (PropertyInfo)member; if (prop.SetMethod != null) { prop.SetValue(obj, value); } } else if (IsField(member)) { var field = (FieldInfo)member; field.SetValue(obj, value); } } public static object GetMemberValue(object obj, MemberInfo member) { object result = null; if (IsProperty(member)) { var prop = (PropertyInfo)member; result = prop.GetValue(obj, prop.GetIndexParameters().Count() == 1 ? new object[] { null } : null); } else if (IsField(member)) { var field = (FieldInfo)member; result = field.GetValue(obj); } return result; } public static bool CanWrite(MemberInfo member) { return IsProperty(member) ? ((PropertyInfo)member).CanWrite : IsField(member); } public static bool CanRead(MemberInfo member) { return IsProperty(member) ? ((PropertyInfo)member).CanRead : IsField(member); } #region 私有方法 private static bool IsProperty(MemberInfo member) { return IsType(member.GetType(), typeof(PropertyInfo)); } private static bool IsField(MemberInfo member) { return IsType(member.GetType(), typeof(FieldInfo)); } private static bool IsType(System.Type type, System.Type targetType) { return type.Equals(targetType) || type.IsSubclassOf(targetType); } #endregion } }