先上代碼:
.net所編寫的程式集包含兩個重要部分:IL(中間語言代碼) 和metadata(元數據)。我們編寫的代碼中不是有很多很多的類嗎,類有很多很多的成員,在編譯代碼的時候,元數據表就根據代碼把類的所有信息都記錄在了它裡面(其實它就是一個數據結構,組織類的信息)。
而反射的過程剛好相反,就是通過元數據里記錄的關於類的詳細信息找到該類的成員,並能使它“複活”(因為元數據里所記錄的信息足夠詳細,以致於可以根據metadata裡面記錄的信息找到關於該類的IL code並加以利用)。
最後對比下:
元數據形成:根據代碼具體內容形成類的記錄信息;
反射:根據元數據的記錄找到所需的代碼;
先上代碼:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.ComponentModel; 7 using System.Linq; 8 using System.Reflection; 9 10 public class reflectModel 11 { 12 13 public static void TestShowReflect() 14 { 15 //反射讀取類私有屬性 16 Person per = new Person("ismallboy", "20102100104"); 17 Type t = per.GetType(); 18 //獲取私有方法 19 MethodInfo method = t.GetMethod("GetStuInfo", BindingFlags.NonPublic | BindingFlags.Instance); 20 //訪問無參數私有方法 21 string strTest = method.Invoke(per, null).ToString(); 22 //訪問有參數私有方法 23 MethodInfo method2 = t.GetMethod("GetValue", BindingFlags.NonPublic | BindingFlags.Instance); 24 object[] par = new object[2]; 25 par[0] = "ismallboy"; 26 par[1] = 2; 27 string strTest2 = method2.Invoke(per, par).ToString(); 28 29 //獲取私有欄位 30 PropertyInfo field = t.GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance); 31 //訪問私有欄位值 32 string value = field.GetValue(per).ToString(); 33 //設置私有欄位值 34 field.SetValue(per, "new Name"); 35 value = field.GetValue(per).ToString(); 36 } 37 } 38 39 40 /// <summary> 41 /// 個人信息 42 /// </summary> 43 class Person 44 { 45 private string Name { get; set; } 46 private string StuNo { get; set; } 47 48 public Person(string name, string stuNo) 49 { 50 this.Name = name; 51 this.StuNo = stuNo; 52 } 53 54 private string GetStuInfo() 55 { 56 return this.Name; 57 } 58 59 private string GetValue(string str, int n) 60 { 61 return str + n.ToString(); 62 } 63 }reflectModel