.Net Framework 中提供了反射機制,可以再加載程序運行時,動態獲取和加載程序集,並且可以獲取到程序集的信息
在程序集中,包含模塊(Module),模塊包含類型,類型包含成員,提供反射,我們可以查看到一個程序集的路徑,命名空間,類。我們還可以對其進行操作
可以對程序集的類進行實例化,掉用類中的方法等,就跟我們普通使用程序集一樣
反射機制通常有下面一些用途
-
使用 Assembly 定義和加載程序集,加載在程序集清單中列出的模塊,以及從此程序集中查找類型並創建該類型的實例。
-
使用 Module 發現以下信息:包含模塊的程序集以及模塊中的類等。 您還可以獲取在模塊上定義的所有全局方法或其他特定的非全局方法。
-
使用 ConstructorInfo 發現以下信息:構造函數的名稱、參數、訪問修飾符(如 public 或 private)和實現詳細信息(如 abstract 或 virtual)等。 使用 Type 的 GetConstructors 或 GetConstructor 方法來調用特定的構造函數。
-
使用 MethodInfo 發現以下信息:方法的名稱、返回類型、參數、訪問修飾符(如 public 或 private)和實現詳細信息(如 abstract 或 virtual)等。 使用 Type 的 GetMethods 或 GetMethod 方法來調用特定的方法。
-
使用 FieldInfo 發現以下信息:字段的名稱、訪問修飾符(如 public 或 private)和實現詳細信息(如static)等;並獲取或設置字段值。
-
使用 EventInfo 發現以下信息:事件的名稱、事件處理程序數據類型、自定義特性、聲明類型和反射類型等;並添加或移除事件處理程序。
-
使用 PropertyInfo 發現以下信息:屬性的名稱、數據類型、聲明類型、反射類型和只讀或可寫狀態等;並獲取或設置屬性值。
-
使用 ParameterInfo 發現以下信息:參數的名稱、數據類型、參數是輸入參數還是輸出參數,以及參數在方法簽名中的位置等。
-
當您在一個應用程序域的僅反射上下文中工作時,請使用 CustomAttributeData 來發現有關自定義特性的信息。 通過使用 CustomAttributeData,您不必創建特性的實例就可以檢查它們。
關於反射,MSDN上有很詳細的說明,這里不詳細講,下面簡單說說反射的使用
http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/f7ykdhsy.aspx
1、為了演示,我們自定義一個類庫,自定義一個類
namespace 環環環環環 { public class User { //字段 public string Field; //屬性 public string Name { get; set; } //構造函數 public User() { this.Name = "無參構造"; } public User(string name) { this.Name = name; } //public函數 public void PublicShow() { Console.WriteLine(string.Format("反射調用一個public方法")); } //private函數 private void PrivateShow() { Console.WriteLine(string.Format("反射調用一個Private方法")); } //static函數 public static string StaticMethod() { return "反射調用了一個Static方法"; } //帶參帶返回值函數 public string GetString(string name) { return string.Format("大家好,我的名字是:{0}!", name); } //事件 public event EventHandler eventHandler; //事件處理函數 public void DoEvent() { if(eventHandler != null) eventHandler(null, EventArgs.Empty); } } }
2、新建一個project,把上面編譯好的庫 環環環環環.dll 復制到Debug目錄下
加載程序集
//獲取程序集 Assembly assembly = Assembly.Load("環環環環環"); Assembly assembly2 = Assembly.LoadFrom("環環環環環.dll"); //從程序集中獲取指定對象類型; Type type = assembly.GetType("環環環環環.User"); //使用Activator創建實例(無參數構造函數) var user1 = Activator.CreateInstance(type); //使用Activator創建實例(帶參數構造函數) var user2 = Activator.CreateInstance(type, "薄暮"); //使用Assembly創建實例(無參數構造函數) var user3 = assembly.CreateInstance("環環環環環.User"); //反射無參構造函數 ConstructorInfo constructor1 = type.GetConstructor(new Type[] {}); var user4 = constructor1.Invoke(new object[] { }); //反射有參構造函數 ConstructorInfo constructor2 = type.GetConstructor(new Type[] { typeof(string) }); var user5 = constructor2.Invoke(new object[] { "薄暮" }); //調用public函數(無參數) type.InvokeMember("PublicShow", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, user1, null); //調用public函數(帶參數) string returnValue = type.InvokeMember("GetString", BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, user1, new object[] { "薄暮" }) as string; // 調用靜態方法 string returnValue2 = type.InvokeMember("StaticMethod", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] {}) as string; // 調用私有方法 . type.InvokeMember("PrivateShow", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, user1, new object[] {}); //反射屬性 var Name = type.InvokeMember("Name", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, user1, new object[] {}) as string; //設置屬性(設置Name屬性為"新屬性") type.InvokeMember("Name", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null, user1, new object[] {"新屬性"}); //反射字段 string Field = type.InvokeMember("Field", BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance, null, user1, new object[] {}) as string; //設置字段(設置Field字段為"新字段") type.InvokeMember("Field", BindingFlags.SetField | BindingFlags.Public | BindingFlags.Instance, null, user1, new object[] { "新字段" });