反射Utilities

   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
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章