221 lines
7.8 KiB
C#
221 lines
7.8 KiB
C#
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<string, object> dictCache = new ConcurrentDictionary<string, object>();
|
|
|
|
#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<PropertyInfo>();
|
|
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<MemberInfo> GetMembers(Type type)
|
|
{
|
|
var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
|
var members = new List<MemberInfo>();
|
|
members.AddRange(type.GetProperties(flags));
|
|
members.AddRange(type.GetFields(flags));
|
|
return members;
|
|
}
|
|
|
|
public static void SetObjectPropertyValue<T>(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<T>(Expression<Func<T>> memberExpression)
|
|
{
|
|
MemberExpression expressionBody = (MemberExpression)memberExpression.Body;
|
|
return expressionBody.Member.Name;
|
|
}
|
|
|
|
public static void SetObjectValue<T>(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<T>(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
|
|
}
|
|
}
|