public static class ReflectionUtilities
{
public static BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
public static BindingFlags bfic = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.IgnoreCase;
#region 反射獲取
/// <summary>
/// 獲取指定對像的指定名稱的字段的值。
/// </summary>
/// <param name="obj">指定對象實例。</param>
/// <param name="name">字段名稱</param>
/// <returns></returns>
public static object GetField(this object obj, string name)
{
FieldInfo fi = obj.GetType().GetField(name, bf);
return fi.GetValue(obj);
}
/// <summary>獲取字段。搜索私有、靜態、基類,優先返回大小寫精確匹配成員</summary>
/// <param name="type">類型</param>
/// <param name="name">名稱</param>
/// <param name="ignoreCase">忽略大小寫</param>
/// <returns></returns>
public static FieldInfo GetField(Type type, String name, Boolean ignoreCase)
{
if (String.IsNullOrEmpty(name)) return null;
// 父類私有字段的獲取需要遞歸,可見範圍則不需要,有些類型的父類爲空,比如接口
while (type != null && type != typeof(Object))
{
//var fi = type.GetField(name, ignoreCase ? bfic : bf);
var fi = type.GetField(name, bf);
if (fi != null) return fi;
if (ignoreCase)
{
fi = type.GetField(name, bfic);
if (fi != null) return fi;
}
type = type.BaseType;
}
return null;
}
/// <summary>獲取成員</summary>
/// <param name="type">類型</param>
/// <param name="name">名稱</param>
/// <param name="ignoreCase">忽略大小寫</param>
/// <returns></returns>
public static MemberInfo GetMember(this Type type, String name, Boolean ignoreCase)
{
// 父類私有成員的獲取需要遞歸,可見範圍則不需要,有些類型的父類爲空,比如接口
while (type != null && type != typeof(Object))
{
var fs = type.GetMember(name, ignoreCase ? bfic : bf);
if (fs != null && fs.Length > 0)
{
// 得到多個的時候,優先返回精確匹配
if (ignoreCase && fs.Length > 1)
{
foreach (var fi in fs)
{
if (fi.Name == name) return fi;
}
}
return fs[0];
}
type = type.BaseType;
}
return null;
}
#endregion
#region 反射調用
public static object InvokeMethod(this object obj, string methodName, object[] args)
{
object objReturn = null;
Type type = obj.GetType();
objReturn = type.InvokeMember(methodName, bf | BindingFlags.InvokeMethod, null, obj, args);
return objReturn;
}
/// <summary>反射調用指定對象的方法</summary>
/// <param name="target">要調用其方法的對象,如果要調用靜態方法,則target是類型</param>
/// <param name="method">方法</param>
/// <param name="parameters">方法參數</param>
/// <returns></returns>
public static Object InvokeMethod(this Object target, MethodBase method, params Object[] parameters)
{
//if (target == null) throw new ArgumentNullException("target");
if (method == null) throw new ArgumentNullException("method");
if (!method.IsStatic && target == null) throw new ArgumentNullException("target");
return method.Invoke(target, parameters);
}
/// <summary>獲取目標對象的成員值</summary>
/// <param name="target">目標對象</param>
/// <param name="member">成員</param>
/// <returns></returns>
[DebuggerHidden]
public static Object GetValue(this Object target, MemberInfo member)
{
if (member is PropertyInfo)
return GetValue(target, member as PropertyInfo);
else if (member is FieldInfo)
return GetValue(target, member as FieldInfo);
else
throw new ArgumentOutOfRangeException("member");
}
/// <summary>獲取指定對象的指定屬性的值。</summary>
/// <param name="target">目標對象</param>
/// <param name="property">屬性</param>
/// <returns></returns>
public static Object GetValue(this Object target, PropertyInfo property)
{
#if dnf40
return property.GetValue(target, null);
#else
return property.GetValue(target);//, null);
#endif
}
/// <summary>獲取指定對象的指定字段的值。</summary>
/// <param name="target">目標對象</param>
/// <param name="field">字段</param>
/// <returns></returns>
public static Object GetValue(this Object target, FieldInfo field)
{
return field.GetValue(target);
}
/// <summary>獲取目標對象指定名稱的屬性/字段值</summary>
/// <param name="target">目標對象</param>
/// <param name="name">名稱</param>
/// <param name="throwOnError">出錯時是否拋出異常</param>
/// <returns></returns>
public static Object GetValue(this Object target, String name, Boolean throwOnError = true)
{
if (target == null) throw new ArgumentNullException("target");
if (String.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
Object value = null;
if (TryGetValue(target, name, out value)) return value;
if (!throwOnError) return null;
var type = GetType(ref target);
throw new ArgumentException("類[" + type.FullName + "]中不存在[" + name + "]屬性或字段。");
}
/// <summary>獲取目標對象指定名稱的屬性/字段值</summary>
/// <param name="target">目標對象</param>
/// <param name="name">名稱</param>
/// <param name="value">數值</param>
/// <returns>是否成功獲取數值</returns>
public static Boolean TryGetValue(this Object target, String name, out Object value)
{
value = null;
if (String.IsNullOrEmpty(name)) return false;
var type = GetType(ref target);
//var pi = GetPropertyEx(type, name);
//if (pi != null)
//{
// value = target.GetValue(pi);
// return true;
//}
//var fi = GetFieldEx(type, name);
//if (fi != null)
//{
// value = target.GetValue(fi);
// return true;
//}
var mi = type.GetMember(name, true);
if (mi == null) return false;
value = target.GetValue(mi);
return true;
}
#endregion
#region 輔助方法
/// <summary>獲取類型,如果target是Type類型,則表示要反射的是靜態成員</summary>
/// <param name="target">目標對象</param>
/// <returns></returns>
static Type GetType(ref Object target)
{
if (target == null) throw new ArgumentNullException("target");
var type = target as Type;
if (type == null)
type = target.GetType();
else
target = null;
return type;
}
/// <summary>判斷某個類型是否可空類型</summary>
/// <param name="type">類型</param>
/// <returns></returns>
static Boolean IsNullable(Type type)
{
//if (type.IsValueType) return false;
if (type.IsGenericType && !type.IsGenericTypeDefinition &&
Object.ReferenceEquals(type.GetGenericTypeDefinition(), typeof(Nullable<>))) return true;
return false;
}
/// <summary>把一個方法轉爲泛型委託,便於快速反射調用</summary>
/// <typeparam name="TFunc"></typeparam>
/// <param name="method"></param>
/// <param name="target"></param>
/// <returns></returns>
public static TFunc As<TFunc>(this MethodInfo method, Object target = null)
{
if (target == null)
return (TFunc)(Object)Delegate.CreateDelegate(typeof(TFunc), method, true);
else
return (TFunc)(Object)Delegate.CreateDelegate(typeof(TFunc), target, method, true);
}
#endregion
#region 判斷是否爲枚舉類型
/// <summary>
/// 判斷是否爲枚舉類型
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static bool IsEnum(this Type type)
{
return type.IsEnum;
}
#endregion
#region 設置對象指定字段的值
/// <summary>
/// 設置對象指定字段的值。
/// </summary>
/// <param name="obj">包含指定字段的對象實例。</param>
/// <param name="name">字段名稱。</param>
/// <param name="value">字段值。</param>
/// <param name="notThrowIfNotExist">如果字段不存在是否拋出異常,默認拋出。</param>
public static void SetField(this object obj, string name, object value, bool notThrowIfNotExist = false)
{
FieldInfo fi = obj.GetType().GetField(name, bf);
if (fi == null)
{
if (notThrowIfNotExist)
return;
else
throw new Exception(string.Format("字段名稱 {0} 不存在。", name));
}
fi.SetValue(obj, value);
}
/// <summary>
/// 設置對象屬性的值
/// </summary>
/// <param name="obj">包含指定屬性的對象實例。</param>
/// <param name="name">屬性名稱。</param>
/// <param name="value">屬性值。</param>
/// <param name="notThrowIfNotExist">如果屬性不存在是否拋出異常,默認拋出。</param>
public static void SetProperty(this object obj, string name, object value, bool notThrowIfNotExist = false)
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(name, bf);
if (propertyInfo == null)
{
if (notThrowIfNotExist)
return;
else
throw new Exception(string.Format("屬性名稱 {0} 不存在。", name));
}
object objValue = ChangeType2(value, propertyInfo.PropertyType);
propertyInfo.SetValue(obj, objValue, null);
}
public static object ChangeType2(this object value, Type conversionType)
{
if (value is DBNull || value == null || string.IsNullOrWhiteSpace(value.ToString()))
return null;
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
System.ComponentModel.NullableConverter nullableConverter
= new System.ComponentModel.NullableConverter(conversionType);
conversionType = nullableConverter.UnderlyingType;
}
return Convert.ChangeType(value, conversionType);
}
#endregion
#region 獲取對象屬性的值
/// <summary>
/// 獲取對象屬性的值
/// </summary>
public static object GetProperty(this object obj, string name)
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(name, bf);
return propertyInfo.GetValue(obj, null);
}
/// <summary>
/// 獲取對象屬性信息(組裝成字符串輸出)
/// </summary>
public static List<string> GetPropertyNames(this object obj)
{
List<string> nameList = new List<string>();
PropertyInfo[] propertyInfos = obj.GetType().GetProperties(bf);
foreach (PropertyInfo property in propertyInfos)
{
nameList.Add(property.Name);
}
return nameList;
}
/// <summary>
/// 獲取對象屬性信息(組裝成字符串輸出)
/// </summary>
public static Dictionary<string, string> GetPropertyNameTypes(this object obj)
{
Dictionary<string, string> nameList = new Dictionary<string, string>();
PropertyInfo[] propertyInfos = obj.GetType().GetProperties(bf);
foreach (PropertyInfo property in propertyInfos)
{
nameList.Add(property.Name, property.PropertyType.FullName);
}
return nameList;
}
public static DataTable CreateTable(object objSource)
{
DataTable table = null;
IEnumerable objList = objSource as IEnumerable;
foreach (object obj in objList)
{
if (table == null)
{
List<string> nameList = ReflectionUtilities.GetPropertyNames(obj);
table = new DataTable("");
DataColumn column;
foreach (string name in nameList)
{
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = name;
column.Caption = name;
table.Columns.Add(column);
}
}
DataRow row = table.NewRow();
PropertyInfo[] propertyInfos = obj.GetType().GetProperties(bf);
foreach (PropertyInfo property in propertyInfos)
{
row[property.Name] = property.GetValue(obj, null);
}
table.Rows.Add(row);
}
return table;
}
#endregion
}
反射Utilities
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.