[原]反射学习整理
一、MSDN上面找的學習資料
反射提供了封裝程序集、模塊和類型的對象(Type 類型)。可以使用反射動態創建類型的實例,將類型綁定到現有對象,或從現有對象獲取類型并調用其方法或訪問其字段和屬性。如果代碼中使用了屬性,可以利用反射對它們進行訪問。
反射通常具有以下用途:
·?? 使用 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,您不必創建屬性的實例就可以檢查它們。
二、反射的重要應用與相關練習
反射在下列情況下很有用:
·?? 需要訪問程序元數據的屬性。
C# 具有一個反射系統,可用來檢索用自定義屬性定義的信息。主要方法是 GetCustomAttributes,它返回對象數組,這些對象在運行時等效于源代碼屬性。
下面是我參照MSDN寫的一個例子:定義一個自定義屬性,將其應用于若干實體并通過反射進行檢索。
?2using?System.Collections.Generic;
?3using?System.Text;
?4
?5namespace?Attribut
?6{
?7????//允許指定多個屬性實例,類YaoJian中進行了練習
?8????[AttributeUsage(AttributeTargets.Class,AllowMultiple?=?true)]
?9????public?class?Students:Attribute
10????{
11????????string?name;
12????????public?int?age;
13????????
14????????public?Students(string?Name)
15????????{
16????????????name?=?Name;
17????????????age?=?18;
18????????}
19
20????????public?string?GetName()
21????????{
22????????????return?name;
23????????}
24????}
25????//將自定義屬性應用于類
26????[Students("李江")]
27????class?LiJiang
28????{
29????????//
30????}
31
32????//不定義Students屬性
33????class?ZhaoYong
34????{
35????????//
36????}
37????//應用多個屬性實例
38????[Students("姚鍵"),Students("李云",age?=?20)]
39????class?YaoJian
40????{
41????????//
42????}
43????class?Program
44????{
45????????static?void?Main(string[]?args)
46????????{
47????????????StudentsInfo(typeof(LiJiang));
48????????????StudentsInfo(typeof(ZhaoYong));
49????????????StudentsInfo(typeof(YaoJian));
50????????}
51
52????????private?static?void?StudentsInfo(Type?t)
53????????{
54????????????Console.WriteLine("學生信息是:{0}",t);
55????????????//獲取對象中的自定義屬性
56????????????Attribute[]?att?=?Attribute.GetCustomAttributes(t);
57????????????foreach?(Attribute?a?in?att)
58????????????{
59????????????????if?(a?is?Students)
60????????????????{
61????????????????????Students?S?=?(Students)a;
62????????????????????Console.WriteLine("學生的姓名是:{0},年齡是:{1}",S.GetName(),S.age.ToString());
63????????????????}
64????????????}
65????????}
66????}
67}
68 運行結果是:
?
·?? 檢查和實例化程序集中的類型。
·?? 在運行時構建新類型。使用 System.Reflection.Emit
中的類。·?? 執行后期綁定,訪問在運行時創建的類型的方法。
三、實踐,用反射調用COM
用反射調用COM非常的方便,不需要先對COM進行注冊添加引用,用Assembly類中的LoadFrom方法直接可以講.dll文件加載到程序中,然后對其實例化使用。
實例:
1、先做一個簡單的調用系統outlook的COM。
先在VS2005中建一個windows控件庫工程,取名為Send,然后把控件的界面刪掉,在Send工程中添加一個windows窗體也取名為Send,在窗體的load事件里面寫代碼調用outlook。完整的代碼如下:?1using?System;
?2using?System.Collections.Generic;
?3using?System.ComponentModel;
?4using?System.Data;
?5using?System.Drawing;
?6using?System.Text;
?7using?System.Windows.Forms;
?8
?9//使用進程引用命名空間
10using?System.Diagnostics;
11namespace?Send
12{
13????public?partial?class?Send?:?Form
14????{
15????????public?Send()
16????????{
17????????????InitializeComponent();
18????????}
19????????/**////?<summary>
20????????///?在Form_Load中調用Windows帶的outlook
21????????///?</summary>
22????????///?<param?name="sender"></param>
23????????///?<param?name="e"></param>
24????????private?void?Send_Load(object?sender,?EventArgs?e)
25????????{
26????????????Process?P?=?new?Process();
27????????????P.StartInfo.FileName?=?"C:\\Program?Files\\Outlook?Express\\msimn.exe";
28????????????P.Start();
29????????????this.Close();
30????????}
31????}
32}
33
代碼寫完以后,生成一下,這時在工程的bin文件夾下面就生成了一個Send.dll的文件。
2、用反射來調用上面的COM
在Send工程的解決方案上面點擊右鍵添加/新建項目/windows應用程序,取名Fanshe在Form1上面添加一個button,并設置其相關屬性,界面如圖:
把上面生成的Send.dll放到Fanshe的bin目錄下面,在button的click事件中添加代碼調用COM,完整代碼如下:
?2using?System.Collections.Generic;
?3using?System.ComponentModel;
?4using?System.Data;
?5using?System.Drawing;
?6using?System.Text;
?7using?System.Windows.Forms;
?8
?9//使用反射引用的命名空間
10using?System.Reflection;
11
12namespace?Fanshe
13{
14????public?partial?class?frm?:?Form
15????{
16????????public?frm()
17????????{
18????????????InitializeComponent();
19????????}
20
21????????private?void?btn_Click(object?sender,?EventArgs?e)
22????????{
23????????????/**//*加載COM,這樣寫COM的默認路徑在bin文件夾下,如果不在可以通過絕對路徑或者相對路徑指到COM所在的位置
24?????????????*比如:Assembly.LoadFrom("D://App//Send.dll")或Assembly.LoadFrom(".//Send.dll")
25?????????????*/
26????????????Assembly?A?=?Assembly.LoadFrom("Send.dll");
27????????????//注意參數中,第一個Send是COM中要實例化類的命名空間名,第二個Send是類名
28????????????Object?O?=?A.CreateInstance("Send.Send");
29????????????Form?F?=?(Form)O;
30????????????F.Show();
31????????}
32????}
33}
34
代碼完成后,將Fanshe設為啟動項并運行,點擊button,調出outlook,界面如下:
?
這個簡單的例子就完成了,里面使用了反射的很少一部分內容,但也可以幫助理解反射機制。
?四、反射的應用要點
1.現實應用程序中很少有應用程序需要使用反射類型?
2.使用反射動態綁定需要犧牲性能?
反射的性能損失主要來源于比較類型、遍歷成員、調用成員三種情形,其中比較類型耗時最小,調用成員耗時最多,所以盡量減少采用成員動態調用等反射方式可以提高應用程序性能。除此之外,采取后期綁定、避免將反射方法放到循環內產生放大效應等辦法均可提升反射性能。
3.有些元數據信息是不能通過反射獲取的?
某些反射類型是專門為那些clr?開發編譯器的開發使用的,所以你要意識到不是所有的反射類型都是適合每個人的。?程序下載:反射掉COM實例
轉載于:https://www.cnblogs.com/salonliudong/archive/2007/10/10/919719.html
總結
- 上一篇: 熊猫烧香源代码(转载)
- 下一篇: hdu 5511 Minimum Cut