一.什么是反射?
反射 Reflection 是提供封裝程序集、模塊和類型的對象
程序集包含模塊,而模塊包含類型,類型又包含成員。反射則提供了封裝程序集、模塊和類型的對象。您可以使用反射動態地創建類型的實例,將類型綁定到現有對象,或從現有對象中獲取類型。然后,可以調用類型的方法或訪問其字段和屬性。
二.反射的用途
1.使用 Assembly 定義和加載程序集,加載在程序集清單中列出的模塊,以及從此程序集中查找類型并創建該類型的實例。
2.使用 Module 了解如下的類似信息:包含模塊的程序集以及模塊中的類等。您還可以獲取在模塊上定義的所有全局方法或其他特定的非全局方法。
3.使用 ConstructorInfo 了解如下的類似信息:構造函數的名稱、參數、訪問修飾符(如 public 或 PRivate)和實現詳細信息(如 abstract 或 virtual)等。4.使用 Type 的 GetConstructors 或 GetConstructor 方法來調用特定的構造函數。
5.使用 MethodInfo 來了解如下的類似信息:方法的名稱、返回類型、參數、訪問修飾符(如 public 或 private)和實現詳細信 息(如 abstract 或 virtual)等。使用 Type 的 GetMethods 或 GetMethod 方法來調用特定的方法。6.使用 FieldInfo 來了解如下的類似信息:字段的名稱、訪問修飾符(如 public 或 private)和實現詳細信息(如 static)等;并獲取或設置字段值。7.使用 EventInfo 來了解如下的類似信息:事件的名稱、事件處理程序數據類型、自定義屬性、聲明類型和反射類型等;并添加或移除事件處理程序。8.使用 PropertyInfo 來了解如下的類似信息:屬性的名稱、數據類型、聲明類型、反射類型和只讀或可寫狀態等;并獲取或設置屬性值。9.使用 ParameterInfo 來了解如下的類似信息:參數的名稱、數據類型、參數是輸入參數還是輸出參數,以及參數在方法簽名中的位置等。三.實例首先,我們創建一個普通的類庫項目Alex.Reflector。如圖1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 namespace Alex.Reflector 6 { 7 public class ReflectorTest 8 { 9 10 public string Name { get; set; }11 /// <summary>12 /// 靜態方法13 /// </summary>14 /// <param name="name"></param>15 /// <returns></returns>16 public static string StaticMethod(string name)17 {18 return name;19 }20 /// <summary>21 /// 實例方法22 /// </summary>23 /// <param name="name"></param>24 /// <returns></returns>25 public string GetNameExample(string name)26 {27 return "Hi" + name;28 }29 /// <summary>30 /// 無參的方法31 /// </summary>32 /// <returns></returns>33 public string GetNoParameter()34 {35 return "沒有參數";36 }37 }38 }
我們生成該類庫項目會在Bin目錄下生成一個Alex.Reflector.dll(根據你項目的名字,這里只是舉例)的文件。
接下來。我們就要用我們的 "反射"技術來操作我們這個DLL文件。
在當前解決方案下新建一個項目名為Alex.ReflectorDemo,如圖然后在此項目下新建一個頁面,我們暫時命名為ReflectorTest.aspx整體結構如圖
ReflectorTest.aspx源碼如下
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ReflectorTest.aspx.cs" Inherits="Alex.ReflectorDemo.ReflectorTest" %> 2 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4 5 <html xmlns="http://www.w3.org/1999/xhtml"> 6 <head runat="server"> 7 <title>C#反射實例</title> 8 </head> 9 <body>10 <form id="form1" runat="server">11 <p>12 <asp:Button ID="btn1" runat="server" Text="利用反射去調用程序集中(包含的類)所包含的方法,屬性,成員" onclick="btn1_Click" />13 </p>14 <asp:Label ID="lblShowMessage" runat="server" Text=""></asp:Label>15 <p>16 </p>17 <p>18 <asp:Button ID="btn2" runat="server" Text="利用反射獲取程序集中類,類的成員(方法,屬性等)" 19 onclick="btn2_Click" />20 </p>21 <asp:Label ID="lblShowMessage1" runat="server" Text=""></asp:Label>22 </form>23 </body>24 </html>
ReflectorTest.aspx.cs源碼如下。在這里我就不一一解釋了。大家一看就懂。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Reflection; 8 9 namespace Alex.ReflectorDemo10 {11 public partial class ReflectorTest : System.Web.UI.Page12 {13 Assembly assembly;14 Type type;15 MethodInfo methodinfo;16 protected void Page_Load(object sender, EventArgs e)17 {18 19 }20 /// <summary>21 /// 利用反射去調用程序集中(包含的類)所包含的方法,屬性,成員22 /// </summary>23 /// <param name="sender"></param>24 /// <param name="e"></param>25 protected void btn1_Click(object sender, EventArgs e)26 {27 try28 {29 assembly = Assembly.LoadFile(@"D:/My/Reflector/Alex.Reflector/Alex.Reflector/bin/Debug/Alex.Reflector.dll");//根據DLL的物理路徑加載30 type = assembly.GetType("Alex.Reflector.ReflectorTest");//根據類型名稱反射出該類型,注意看格式是命名空間.類名31 object strobject = Activator.CreateInstance(type);//創建該類型的對象實例32 methodinfo = type.GetMethod("GetNameExample");//反射獲取方法。實例方法33 string s = (string)methodinfo.Invoke(strobject, new string[] { "田小賤" });34 lblShowMessage.Text = "調用實例方法返回:" + s.ToString()+"</br>";35 36 methodinfo = type.GetMethod("StaticMethod");37 string s1 = (string)methodinfo.Invoke(null, new string[] { "肖小仙" });38 lblShowMessage.Text += "調用靜態方法返回:" + s1.ToString();39 type.GetProperty("Name").SetValue(strobject, "田小賤", null);40 }41 catch (Exception)42 {43 throw;44 }45 finally46 {47 assembly = null;48 type = null;49 methodinfo = null;50 51 }52 }53 /// <summary>54 /// 利用反射獲取程序集中類,類的成員(方法,屬性等)55 /// </summary>56 /// <param name="sender"></param>57 /// <param name="e"></param>58 protected void btn2_Click(object sender, EventArgs e)59 {60 assembly = Assembly.LoadFile(@"D:/My/Reflector/Alex.Reflector/Alex.Reflector/bin/Debug/Alex.Reflector.dll");//根據DLL的物理路徑加載61 Module[] module = assembly.GetModules();//獲取作為程序集的一部分的所有模塊62 Type[] types = assembly.GetTypes(); //獲取程序集中定義的所有類型63 64 foreach (var item in types)65 {66 lblShowMessage1.Text ="所包含的類型名稱:"+ item.Name+"</br>";67 MethodInfo[] methodinfos=item.GetMethods();// (MethodInfo)發現方法的屬性,并提供對方法元數據的訪問)獲取該類型下所包含的方法信息68 foreach (var method in methodinfos)69 {70 lblShowMessage1.Text += "該類所包含的方法名稱:"+method.Name+"</br>";71 }72 PropertyInfo[] propertyInfo = item.GetProperties();//(ProperInfo)發現屬性的特性,并提供對該屬性元數據的訪問73 74 foreach (var property in propertyInfo)75 {76 lblShowMessage1.Text += "該類所包含的屬性名稱:" + property.Name; ;77 }78 }79 80 } 81 }82 }View Code
多話不說,直接看運行效果。
最后。提醒大家一下。反射相對來說會影響性能。 希望大家根據自己實際情況去合理使用。
新聞熱點
疑難解答