一、組件的載入
JIT編譯器器將IL程式碼編譯成本地程式碼時, 會查看IL程式碼中引用了哪些型別。在運行過程中,JIT編譯器利用組件的TypeRef和AssemblyRef元資料表來決定哪一個組件定義了所引用的類型,然後JIT編譯器將對應組件載入到AppDomain中,在內部,CLR使用System .Reflection.Assembly類別的靜態方法Load來嘗試載入一個組件。然而如果我們想要動態載入一個組件時,可以使用Assembly的Load方法來動態載入組件,其中Assembly類別中也提供了其他的載入組件方法,有LoadFrom(string path), LoadFile(stringassemblyFile)等。
二、反射機制
.net中反射在運行中過程中解析程式集中的元數據,獲得類型中的成員(包括欄位、建構器、方法、屬性、事件等)資訊。
把下面的類別放在一個類別庫工程中,並編譯生成組件(例如為ClassLibrary1.dll,假設把dll放在D盤根目錄下面)
public class ReflectTestClass { public string name; public int age; public string Name { get { return name; } set { name = value; } } public int Age { get { return age; } set { age = value; } } /// <summary> /// No Paramter Constructor /// </summary> public ReflectTestClass() { } /// <summary> /// Constructor with Parameter /// </summary> /// <param name="name"></param> /// <param name="age"></param> public ReflectTestClass(string names,int ages) { this.name = names; this.age = ages; } public string writeString(string name) { return "Welcome " + name; } public static string WriteName(string name) { return "Welcome "+name +" Come here"; } public string WirteNopara() { return "The method is no parameter "; } }
然後建立一個控制台程式用來動態載入上面產生的組件和輸出類型中的成員,程式碼中有詳細的介紹。
class Program { static void Main(string[] args) { Assembly ass; Type[] types; Type typeA; object obj; try { // 从本地中 加载程序集 然后从程序集中通过反射获得类型的信息的,并且调用方法 ass = Assembly.LoadFrom(@"D:\ClassLibrary1.dll"); types = ass.GetTypes(); foreach (Type type in types) { Console.WriteLine("Class Name is " + type.FullName); Console.WriteLine("Constructor Information"); Console.WriteLine("-----------------------"); // 获取类型的结构信息 ConstructorInfo[] myconstructors = type.GetConstructors(); ShowMessage<ConstructorInfo>(myconstructors); Console.WriteLine("Fields Information"); Console.WriteLine("-----------------------"); // 获取类型的字段信息 FieldInfo[] myfields = type.GetFields(); ShowMessage<FieldInfo>(myfields); Console.WriteLine("All Methods Information"); Console.WriteLine("-----------------------"); // 获取方法信息 MethodInfo[] myMethodInfo = type.GetMethods(); ShowMessage<MethodInfo>(myMethodInfo); Console.WriteLine("All Properties Information"); Console.WriteLine("-----------------------"); // 获取属性信息 PropertyInfo[] myproperties = type.GetProperties(); ShowMessage<PropertyInfo>(myproperties); } // 用命名空间+类名获取类型 typeA = ass.GetType("ClassLibrary1.ReflectTestClass"); // 获得方法名称 MethodInfo method = typeA.GetMethod("writeString"); // 创建实例 obj = ass.CreateInstance("ClassLibrary1.ReflectTestClass"); string result = (String)method.Invoke(obj,new string[] {"Tom"}); Console.WriteLine("Invoke Method With Parameter"); Console.WriteLine("-----------------------"); Console.WriteLine(result); Console.WriteLine("-----------------------"); Console.WriteLine(); method = typeA.GetMethod("WriteName"); result = (string)method.Invoke(null,new string[] {"Tom"}); Console.WriteLine("Invoke Static Method with Parameter"); Console.WriteLine("-----------------------"); Console.WriteLine(result); Console.WriteLine("-----------------------"); Console.WriteLine(); method = typeA.GetMethod("WirteNopara"); Console.WriteLine("Invoke Method with NOParameter"); result = (string)method.Invoke(obj, null); Console.WriteLine("-----------------------"); Console.WriteLine(result); Console.WriteLine("-----------------------"); } catch(FileNotFoundException ex) { Console.WriteLine(ex.Message); } Console.ReadLine(); } /// <summary> /// 显示数组信息 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="os"></param> public static void ShowMessage<T>(T[] array) { foreach(T member in array) { Console.WriteLine(member.ToString()); } Console.WriteLine("-----------------------"); Console.WriteLine(); } }
篩選回傳的成員種類
可以呼叫Type的GetMembers,GetFields,GetMethods,GetProperties或GetEvenents方法來查詢一個類型的成員。在呼叫上面的任何一個方法時,都可以傳遞System.Reflection.BindingFlags枚舉類型的一個實例,使用這個枚舉類型目的是對這些方法傳回的成員進行篩選。
注意:在傳回一個成員集合的所有方法中, 都有一個不取得任何實參的重載版本。如果不傳遞BindingFlags實參,所有這些方法都傳回公共成員,預設為BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static. (如果指定Public或NonPublic,那麼必須同時指定Instance,否則不回傳成員)。
以上是Java中的程式集載入和反射機制是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!