| 一、反射的概念 :反射的概念是由Smith在1982年首次提出的,主要是指程式可以訪問、檢測和修改它本身狀態或行為的一種能力。這一概念的提出很快引發了電腦科學領域關於應用反射性的研究。它首先被程式語言的設計領域所採用,並在Lisp和物件導向方面取得了成績。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基於反射機制的語言。最近,反射機制也被應用到了視窗系統、作業系統和檔案系統中。 反射本身並不是一個新概念,它可能會使我們聯想到光學中的反射概念,儘管電腦科學賦予了反射概念新的含義,但是,從現象上來說,它們確實有某些相通之處,這些有助於我們的理解。在電腦科學領域,反射是指一類應用,它們能夠自描述和自控制。也就是說,這類應用通過採用某種機制來實現對自己行為的描述(self-representation)和監測(examination),並能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。可以看出,同一般的反射概念相比,電腦科學領域的反射不單單指反射本身,還包括對反射結果所採取的措施。所有採用反射機制的系統(即反射系統)都希望使系統的實現更開放。可以說,實現了反射機制的系統都具有開放性,但具有開放性的系統並不一定採用了反射機制,開放性是反射系統的必要條件。一般來說,反射系統除了滿足開放性條件外還必須滿足原因串連(Causally-connected)。所謂原因串連是指對反射系統自描述的改變能夠立即反映到系統底層的實際狀態和行為上的情況,反之亦然。開放性和原因串連是反射系統的兩大基本要素。 反射,Reflection,通過它我們可以在運行時獲得各種資訊,如程式集、模組、類型、欄位、屬性、方法和事件 通過對類型動態執行個體化後,還可以對其執行操作 一般用於外掛程式式架構程式和設計模式的實現,當然反射是一種手段可以充分發揮其能量來完成你想做的任何事情(前面好象見過一位高人用反射調用一個官方類庫中未說明的函數。。。) 樣本: using System; using System.Collections.Generic; using System.Text; namespace Example25Lib { public class Class1 { private string name; private int age; //如果顯式的聲明了無參數建構函式,用戶端只需要用程式集的CreateInstance即可執行個體化該類 //在此特意不實現,以便在客戶調用端體現建構函式的反射實現 //public Class1() //{ //} public Class1(string Name, int Age) { name = Name; age = Age; } public void ChangeName(string NewName) { name = NewName; } public void ChangeAge(int NewAge) { age = NewAge; } public override string ToString() { return string.Format("Name: {0}, Age: {1}", name, age); } } } 反射執行個體化對象並調用其方法,屬性和事件的反射調用略去 using System; using System.Collections.Generic; using System.Text; //注意添加該反射的命名空間 using System.Reflection; namespace Example25 { class Program { static void Main(string[] args) { //載入程式集 Assembly tmpAss = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + "Example25Lib.dll"); //遍曆程式集內所有的類型,並執行個體化 Type[] tmpTypes = tmpAss.GetTypes(); foreach (Type tmpType in tmpTypes) { //擷取第一個類型的建構函式資訊 ConstructorInfo[] tmpConsInfos = tmpType.GetConstructors(); foreach (ConstructorInfo tmpConsInfo in tmpConsInfos) { //為建構函式產生調用的參數集合 ParameterInfo[] tmpParamInfos = tmpConsInfo.GetParameters(); object[] tmpParams = new object[tmpParamInfos.Length]; for (int i = 0; i < tmpParamInfos.Length; i++) { tmpParams[i] = tmpAss.CreateInstance(tmpParamInfos[i].ParameterType.FullName); if (tmpParamInfos[i].ParameterType.FullName == "System.String") { tmpParams[i] = "Clark"; } } //執行個體化對象 object tmpObj = tmpConsInfo.Invoke(tmpParams); Console.WriteLine(tmpObj); //擷取所有方法並執行 foreach (MethodInfo tmpMethod in tmpType.GetMethods()) { //為方法的調用建立參數集合 tmpParamInfos = tmpMethod.GetParameters(); tmpParams = new object[tmpParamInfos.Length]; for (int i = 0; i < tmpParamInfos.Length; i++) { tmpParams[i] = tmpAss.CreateInstance(tmpParamInfos[i].ParameterType.FullName); if (tmpParamInfos[i].ParameterType.FullName == "System.String") { tmpParams[i] = "Clark Zheng"; } if (tmpParamInfos[i].ParameterType.FullName == "System.Int32") { tmpParams[i] = 27; } } tmpMethod.Invoke(tmpObj, tmpParams); } //調用完方法後再次列印對象,比較結果 Console.WriteLine(tmpObj); } } Console.ReadLine(); } } } 結果: Name: Clark, Age: 0 Name: Clark Zheng, Age: 27 |