程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#基礎系列——反射筆記

C#基礎系列——反射筆記

編輯:C#入門知識

C#基礎系列——反射筆記


前言:使用反射也有幾年了,但是一直覺得,反這個概念很抽象,今天有時間就來總結下這個知識點。       1、為什麼需要反射:     最初使用反射的時候,作為小菜總是不理解,既然可以通過new 一個對象的方式得到對象,然後通過對象去調用屬性和方法,那麼為什麼還需要反射去調用呢?後來使用多了發現這就是一個先綁定還是後綁定的問題,很多初使用反射的開發人員通常都會有類似這種疑慮:既然在開發時就能夠寫好代碼,干嘛還放到運行期去做,不光繁瑣,而且效率也受影響。博主覺得主要是適用性的問題,如果你的系統沒有那麼高的擴展性和靈活性要求,你大可不必考慮反射。但在架構設計時,很多東西都需要考慮復用性,並且在某些特定的場景下你得不到具體的類時,你就必須用到反射。博主總結了下自己使用過的反射場景:   (1)有時不知道具體的類型,可以通過dll去得到類的對象;   (2)某些特殊方法,傳過來的是泛型類,需要通過反射處理某些特殊的業務;   (3)通用方法DataTable和List<T>的相互轉化時需要用到反射;       2、如何使用反射:   (1)反射dll得到類成員:   在一個未知的dll裡面有一個Person類    
    public class Person
    {
        private string address;
        private string email;

        public string Name { set; get; }

        public int Age { set; get; }

        public void SayHello()
        {
            Console.WriteLine("你好");
        }

        public static string MystaticPro { set; get; }
        public static void MyStatic()
        {
            Console.WriteLine("我是static方法");
        }
    }
 

 

    通過反射dll得到Person類    
        static void Main(string[] args)
        {
            //反射dll
            var strDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll\\ReflectorDLL.dll");
            var oAssembly = Assembly.LoadFile(strDllPath);
            var lstTypes = oAssembly.GetTypes();
            foreach (var oType in lstTypes)
            {
                if (oType.Name == "Person")
                {
                    //默認得到類下面的所有public成員
                    var lstMembers = oType.GetMembers();
                    foreach (var oMem in lstMembers)
                    {
                        Console.WriteLine("GetMembers()方法得到的成員名稱:"+oMem.Name);
                    }
                    Console.WriteLine("");

                    //默認得到類下面的所有public屬性
                    var lstProperty = oType.GetProperties();
                    foreach (var oProp in lstProperty)
                    {
                        Console.WriteLine("GetProperties()方法得到的成員名稱:" + oProp.Name);
                    }
                    Console.WriteLine("");

                    //默認得到類下面的所有public字段
                    var lstField = oType.GetFields();
                    foreach (var oField in lstField)
                    {
                        Console.WriteLine("GetFields()方法得到的成員名稱:" + oField.Name);
                    }
                }
            }

            Console.ReadKey();
        }

 

    得到結果       (2)反射對象的私有成員:   一般私有屬性的用法比較少,我們就以私有字段為例來說明,還是上面的例子:    
        static void Main(string[] args)
        {
            //反射dll
            var strDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll\\ReflectorDLL.dll");
            var oAssembly = Assembly.LoadFile(strDllPath);
            var lstTypes = oAssembly.GetTypes();
            foreach (var oType in lstTypes)
            {
                if (oType.Name == "Person")
                {
                    //默認得到類下面的所有public字段
                    var lstField = oType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
                    foreach (var oField in lstField)
                    {
                        Console.WriteLine("GetFields()方法得到的成員名稱:" + oField.Name);
                    }
                }
            }

            Console.ReadKey();
        }
 

 

        (3)反射對象的靜態成員:    
      static void Main(string[] args)
        {
            //反射dll
            var strDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll\\ReflectorDLL.dll");
            var oAssembly = Assembly.LoadFile(strDllPath);
            var lstTypes = oAssembly.GetTypes();
            foreach (var oType in lstTypes)
            {
                if (oType.Name == "Person")
                {
                    //默認得到類下面的所有public成員
                    var lstMembers = oType.GetMembers(BindingFlags.Public|BindingFlags.Static);
                    foreach (var oMem in lstMembers)
                    {
                        Console.WriteLine("GetMembers()方法得到的成員名稱:" + oMem.Name);
                    }
                    Console.WriteLine("");

                    //默認得到類下面的所有public字段
                    var lstField = oType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
                    foreach (var oField in lstField)
                    {
                        Console.WriteLine("GetFields()方法得到的成員名稱:" + oField.Name);
                    }
                }
            }

            Console.ReadKey();
        }
 

 

    還有枚舉類型等等就不一一介紹了,基本上都是在BindingFlags這個上面做處理。       (4)反射得到對象以及對象的操作:   反射得到對象的方法主要有兩種    
      public static T GetModel<T>(T oModel)
        {
            var model = default(T) ;
            
            //得到對象的方法一:
            model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });//反射得到泛型類的實體

            //得到對象的方法二:
            model = (T)Activator.CreateInstance(typeof(T));

            //邏輯處理......
            
            return model;
        }

 

     對象屬性的取值和賦值:    
      //List集合轉換為DataTable
        public static DataTable ListFillTable(object obj)
        {
            if (!(obj is IList))
            {
                return null;
            }
            var objlist = obj as IList;
            if (objlist == null || objlist.Count <= 0)
            {
                return null;
            }
            var tType = objlist[0];
            DataTable dt = new DataTable(tType.GetType().Name);
            DataColumn column;
            DataRow row;
            System.Reflection.PropertyInfo[] myPropertyInfo = tType.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var t in objlist)
            {
                if (t == null)
                {
                    continue;
                }
                row = dt.NewRow();
                for (int i = 0, j = myPropertyInfo.Length; i < j; i++)
                {
                    System.Reflection.PropertyInfo pi = myPropertyInfo[i];
                    string name = pi.Name;
                    if (dt.Columns[name] == null)
                    {
                        var coltype = pi.PropertyType;
                        if (coltype.Name == "Nullable`1")
                        {
                            //coltype = typeof(System.DBNull);
                            column = new DataColumn(name);
                        }
                        else
                        {
                            column = new DataColumn(name, coltype);
                        }
                        dt.Columns.Add(column);
                    }
                    row[name] = pi.GetValue(t, null);
                }
                dt.Rows.Add(row);
            }
            return dt;
        }

 

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved