.net core 反射的介紹與使用

  1. 概述反射

  • 經過反射能夠提供類型信息,從而使得咱們開發人員在運行時可以利用這些信息構造和使用對象。 
  •  反射機制容許程序在執行過程當中動態地添加各類功能。  

  2. Type類的介紹  數據庫

  • 是BCL(基底類別庫)聲明的一個抽象類,全部它不能被實例化
  • 對於程序中用到的每個類型,CLR(公共語言運行時)都會建立一個包含這個類型信息的Type類型的對象
  • 程序中用到的每個類型都會關聯到獨立的Type類型的對象
  • 無論建立的類型有多少個實例,只有一個Type對象會關聯到全部這些實例

    2.1 Type類的部分常見成員

    成員 成員類型 描述
    Name 屬性 返回類型的名字
    FullName 屬性 返回數據類型的徹底限定名(包括命名空間名)
    NameSpace 屬性 返回包含數據類型聲明的命名空間
    Assembly 屬性 返回聲明類型的程序集。若是類型是泛型的,返回定義這個類型的程序集
    GetConstructor(), GetConstructors() 方法 返回ConstructorInfo類型,用於取得該類的構造函數的信息
    GetEvent(), GetEvents() 方法 返回EventInfo類型,用於取得該類的事件的信息
    GetField(), GetFields() 方法 返回FieldInfo類型,用於取得該類的字段(成員變量)的信息
    GetInterface(), GetInterfaces() 方法 返回InterfaceInfo類型,用於取得該類實現的接口的信息
    GetMember(), GetMembers() 方法 返回MemberInfo類型,用於取得該類的全部成員的信息
    GetMethod(), GetMethods() 方法 返回MethodInfo類型,用於取得該類的方法的信息
    GetProperty(), GetProperties() 方法 返回PropertyInfo類型,用於取得該類的屬性的信息

  3. 如何獲取Type類型數組

   3.1GetType()和typeof() 方法 二者都是返回Syetem.Type的引用。(private和protected修飾的成員也能夠訪問到)ide

       3.1.1 GetType()函數

              1.GetType()是從Syetem.object中基礎的方法。spa

              2.GetType()必需要經過類型的實例點出這個方法。.net

       3.1.2 typeof()code

              1.typeof(xx)是公開的運算符。對象

              2.typeof(xx)中xx只能是int,string 等類型及自定義類型,不能是實例。blog

      3.2 不一樣點繼承

            1.GetType()返回的是Type(類型)

               2.typeof(xx) 返回的是xx Class(類)的類型

 1  //實例一個用戶類
 2             User user = new User();
 3             //GetType()方法
 4             Type getType = user.GetType();
 5             //typeof(xx) 方法
 6             Type typeOf = typeof(User);
 7             //判斷是否相等
 8             if (getType == typeOf)
 9             {
10                 //這裏相等
11                 Console.WriteLine("我在這");
12             }

 4.Type類方法        

  1: 一旦有了Type對象就可使用GetMethodInfo()方法獲取此類型支持的方法列表。該方法返回一個MethodInfo 對象數組,MethodInfo對象描述了主調類型所支持的方法,他位於System.Reflection命名空間中

  2: MethodInfo類派生於MethodBase抽象類,而MethodBase類繼承了MemberInfo類。所以咱們可以使用這三個類定義的屬性和方法。例如,使用Name屬性獲得方法名稱。這裏有兩個重要的成員:

  3: ReturnType屬性 :爲Type類型的對象,可以提供方法的返回類型信息 GetParameters()方法 :返回參數列表,參數信息以數組形式保存在PatameterInfo對象中。PatameterInfo類定義了大量描述參數信息的屬性和方法。這裏也列出兩個經常使用的屬性 :Name(包含參數名稱信息的字符串),ParameterType(參數類型的信息)。

//建立實例
            Sublevel sublevel = new Sublevel();
            //獲取類型
            Type sublevelType = sublevel.GetType();
            //獲取類型的方法列表
            //BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public 這個有一個注意點
            //實際上至少要有Instance(或Static)與Public(或NonPublic)標記。不然將不會獲取任何方法。
            MethodInfo[] obj = sublevelType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
            //遍歷全部的方法
            foreach (MethodInfo item in obj)
            {
                //返回方法的返回類型
                Console.Write(item.ReturnType.Name);
                //返回方法的名稱
                Console.Write(" "+item.Name+"(");
                //獲取方法的返回參數列表
                ParameterInfo[] parameterss = item.GetParameters();
                foreach (var parameters in parameterss)
                {
                    //參數類型名稱
                    Console.Write(parameters.ParameterType.Name);
                    //參數名稱
                    Console.Write(" "+parameters.Name+",");
                }
                Console.WriteLine(")");
            }

 

執行的結果,獲取了全部的方法,包括了方法的方法名稱,方法的返回類型,方法參數列表。

5.方法的使用

    前面咱們講了放的顯示,可是隻能看到不能用就很差了呀!!!

    5.1:GetMethods()方法的另外一種形式

        這種形式能夠制定各類標記,已篩選想要獲取的方法。他的通用形式爲:MethodInfo[] GetMethods(BindingFlags bindingAttr)BindingFlags是一個枚舉,枚舉值有(不少只列出4個吧)

  1. Instance:獲取實例方法
  2. NonPublic: 獲取非公有方法
  3. Public: 獲取共有方法
  4. Static:獲取靜態方法

        GetMethods(BindingFlags bindingAttr)這個方法,參數可使用or把兩個或更多標記鏈接在一塊兒,實際上至少要有Instance(或Static)與Public(或NonPublic)標記。不然將不會獲取任何方法。

        static void Main(string[] args)
        {
            //建立實例
            Sublevel sublevel = new Sublevel();
            //獲取類型
            Type sublevelType = sublevel.GetType();
            //獲取類型的方法列表
            //BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public 這個有一個注意點
            //實際上至少要有Instance(或Static)與Public(或NonPublic)標記。不然將不會獲取任何方法。
            MethodInfo[] obj = sublevelType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
            //遍歷全部的方法
            foreach (MethodInfo item in obj)
            {
                //返回方法的返回類型
                Console.Write(item.ReturnType.Name);
                //返回方法的名稱
                Console.Write(" "+item.Name+"(");
                //獲取方法的返回參數列表
                ParameterInfo[] parameterss = item.GetParameters();
                foreach (var parameters in parameterss)
                {
                    //參數類型名稱
                    Console.Write(parameters.ParameterType.Name);
                    //參數名稱
                    Console.Write(" "+parameters.Name+",");
                }
                Console.WriteLine(")");
            }
            //獲取類型的屬性列表
            var obj1 = sublevelType.GetProperties(BindingFlags.NonPublic|BindingFlags.Instance | BindingFlags.Public);
            //獲取類型的成員列表
            var obj2 = sublevelType.GetMembers(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
            //獲取類型的構造函數列表
            var obj3 = sublevelType.GetConstructors();
        }

        public class Student
        {
            /// <summary>
            /// 主鍵
            /// </summary>
            public int id { get; set; }
            /// <summary>
            /// 名稱
            /// </summary>
            public string name { get; set; }

            /// <summary>
            /// 年齡
            /// </summary>
            public static int age { get; set; }

            /// <summary>
            /// 無參構造函數
            /// </summary>
            public Student()
            {
                Console.WriteLine("無參構造函數");
            }

            /// <summary>
            /// 有參構造函數
            /// </summary>
            /// <param name="Name">名稱</param>
            public Student(string Name)
            {
                name = Name;
                Console.WriteLine(name);
            }

            /// <summary>
            /// 獲取名稱
            /// </summary>
            /// <param name="Name">名稱</param>
            /// <returns></returns>
            public string GetName(string Name)
            {
                name = Name;
                return name;
            }

            /// <summary>
            /// 獲取年齡(靜態方法)
            /// </summary>
            /// <param name="Age">年齡</param>
            /// <returns></returns>
            public static int GetAge(int Age)
            {
                age = Age + 5;
                return age;
            }
        }

 

 

6.DataTable轉Model(List)

   在剛剛學.net 的時候,咱們從數據庫查詢出一個DataTable的時候想要轉成Model或者LIst的時候咱們須要手動的寫遍歷,超級麻煩(在沒有接觸MVC的時候我就是)

 /// <summary>
    /// DataTable轉換
    /// </summary>
    public class TransitionDataTable
    {
        /// <summary>
        ///  DataTable轉換模型
        /// </summary>
        /// <typeparam name="T">模型類型</typeparam>
        /// <param name="obj">模型</param>
        /// <param name="data">數據行</param>
        /// <returns></returns>
        public T DataSetBindModel<T>(T obj, DataTable data) where T : class, new()
        {
            T result = new T();
            foreach (DataRow item in data.Rows)
            {
                result = assignmentClass(obj, item);
            }
            return result;
        }

        /// <summary>
        /// DataTable轉換List
        /// </summary>
        /// <typeparam name="T">模型類型</typeparam>
        /// <param name="obj">模型</param>
        /// <param name="data">數據行</param>
        /// <returns></returns>
        public List<T> DataSetBindList<T>(T obj, DataTable data) where T : class, new()
        {
            List<T> result = new List<T>();
            foreach (DataRow item in data.Rows)
            {
                result.Add(assignmentClass(obj, item));
            }
            return result;
        }

        /// <summary>
        /// DataRow 轉換成模型
        /// </summary>
        /// <typeparam name="T">模型類型</typeparam>
        /// <param name="obj">模型</param>
        /// <param name="row">數據行</param>
        /// <returns></returns>
        private T assignmentClass<T>(T obj, DataRow row) where T : class, new()
        {
            if (obj == null)
            {
                obj = new T();
            }
            Type type = obj.GetType();
            //獲得類型的全部屬性,也就是表對應的實體模型的全部屬性
            //嗮選一下只要公開的
            PropertyInfo[] properts = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            if (properts.Any())
            {
                foreach (PropertyInfo item in properts)
                {
                    if (row.Table.Columns.IndexOf(item.Name) != -1)
                    {
                        if (row[item.Name] != null && row[item.Name] != DBNull.Value)
                        {
                            item.SetValue(obj, row[item.Name]);
                        }
                    }
                }
            }
            return obj;
        }
    }
View Code

相關文章
相關標籤/搜索