[原]反射学习整理
一、MSDN上面找的學(xué)習(xí)資料
反射提供了封裝程序集、模塊和類型的對(duì)象(Type 類型)。可以使用反射動(dòng)態(tài)創(chuàng)建類型的實(shí)例,將類型綁定到現(xiàn)有對(duì)象,或從現(xiàn)有對(duì)象獲取類型并調(diào)用其方法或訪問其字段和屬性。如果代碼中使用了屬性,可以利用反射對(duì)它們進(jìn)行訪問。
反射通常具有以下用途:
·?? 使用 Assembly 定義和加載程序集,加載在程序集清單中列出的模塊,以及從此程序集中查找類型并創(chuàng)建該類型的實(shí)例。
·?? 使用 Module 了解如下的類似信息:包含模塊的程序集以及模塊中的類等。您還可以獲取在模塊上定義的所有全局方法或其他特定的非全局方法。
·?? 使用 ConstructorInfo 了解以下信息:構(gòu)造函數(shù)的名稱、參數(shù)、訪問修飾符(如 public 或 private)和實(shí)現(xiàn)詳細(xì)信息(如 abstract 或 virtual)等。使用 Type 的 GetConstructors 或 GetConstructor 方法來調(diào)用特定的構(gòu)造函數(shù)。
·?? 使用 MethodInfo 了解以下信息:方法的名稱、返回類型、參數(shù)、訪問修飾符(如 public 或 private)和實(shí)現(xiàn)詳細(xì)信息(如 abstract 或 virtual)等。使用 Type 的 GetMethods 或 GetMethod 方法來調(diào)用特定的方法。
·?? 使用 FieldInfo 了解以下信息:字段的名稱、訪問修飾符(如 public 或 private)和實(shí)現(xiàn)詳細(xì)信息(如 static)等;并獲取或設(shè)置字段值。
·?? 使用 EventInfo 來了解如下的類似信息:事件的名稱、事件處理程序數(shù)據(jù)類型、自定義屬性、聲明類型和反射類型等;并添加或移除事件處理程序。
·?? 使用 PropertyInfo 來了解如下的類似信息:屬性的名稱、數(shù)據(jù)類型、聲明類型、反射類型和只讀或可寫狀態(tài)等;并獲取或設(shè)置屬性值。
·?? 使用 ParameterInfo 來了解如下的類似信息:參數(shù)的名稱、數(shù)據(jù)類型、參數(shù)是輸入?yún)?shù)還是輸出參數(shù),以及參數(shù)在方法簽名中的位置等。
·?? 當(dāng)您在一個(gè)應(yīng)用程序域的僅反射上下文中工作時(shí),請(qǐng)使用 CustomAttributeData 來了解有關(guān)自定義屬性的信息。使用 CustomAttributeData,您不必創(chuàng)建屬性的實(shí)例就可以檢查它們。
二、反射的重要應(yīng)用與相關(guān)練習(xí)
反射在下列情況下很有用:
·?? 需要訪問程序元數(shù)據(jù)的屬性。
C# 具有一個(gè)反射系統(tǒng),可用來檢索用自定義屬性定義的信息。主要方法是 GetCustomAttributes,它返回對(duì)象數(shù)組,這些對(duì)象在運(yùn)行時(shí)等效于源代碼屬性。
下面是我參照MSDN寫的一個(gè)例子:定義一個(gè)自定義屬性,將其應(yīng)用于若干實(shí)體并通過反射進(jìn)行檢索。
?2using?System.Collections.Generic;
?3using?System.Text;
?4
?5namespace?Attribut
?6{
?7????//允許指定多個(gè)屬性實(shí)例,類YaoJian中進(jìn)行了練習(xí)
?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????//將自定義屬性應(yīng)用于類
26????[Students("李江")]
27????class?LiJiang
28????{
29????????//
30????}
31
32????//不定義Students屬性
33????class?ZhaoYong
34????{
35????????//
36????}
37????//應(yīng)用多個(gè)屬性實(shí)例
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("學(xué)生信息是:{0}",t);
55????????????//獲取對(duì)象中的自定義屬性
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("學(xué)生的姓名是:{0},年齡是:{1}",S.GetName(),S.age.ToString());
63????????????????}
64????????????}
65????????}
66????}
67}
68 運(yùn)行結(jié)果是:
?
·?? 檢查和實(shí)例化程序集中的類型。
·?? 在運(yùn)行時(shí)構(gòu)建新類型。使用 System.Reflection.Emit
中的類。·?? 執(zhí)行后期綁定,訪問在運(yùn)行時(shí)創(chuàng)建的類型的方法。
三、實(shí)踐,用反射調(diào)用COM
用反射調(diào)用COM非常的方便,不需要先對(duì)COM進(jìn)行注冊(cè)添加引用,用Assembly類中的LoadFrom方法直接可以講.dll文件加載到程序中,然后對(duì)其實(shí)例化使用。
實(shí)例:
1、先做一個(gè)簡單的調(diào)用系統(tǒng)outlook的COM。
先在VS2005中建一個(gè)windows控件庫工程,取名為Send,然后把控件的界面刪掉,在Send工程中添加一個(gè)windows窗體也取名為Send,在窗體的load事件里面寫代碼調(diào)用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//使用進(jìn)程引用命名空間
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中調(diào)用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
代碼寫完以后,生成一下,這時(shí)在工程的bin文件夾下面就生成了一個(gè)Send.dll的文件。
2、用反射來調(diào)用上面的COM
在Send工程的解決方案上面點(diǎn)擊右鍵添加/新建項(xiàng)目/windows應(yīng)用程序,取名Fanshe在Form1上面添加一個(gè)button,并設(shè)置其相關(guān)屬性,界面如圖:
把上面生成的Send.dll放到Fanshe的bin目錄下面,在button的click事件中添加代碼調(diào)用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的默認(rèn)路徑在bin文件夾下,如果不在可以通過絕對(duì)路徑或者相對(duì)路徑指到COM所在的位置
24?????????????*比如:Assembly.LoadFrom("D://App//Send.dll")或Assembly.LoadFrom(".//Send.dll")
25?????????????*/
26????????????Assembly?A?=?Assembly.LoadFrom("Send.dll");
27????????????//注意參數(shù)中,第一個(gè)Send是COM中要實(shí)例化類的命名空間名,第二個(gè)Send是類名
28????????????Object?O?=?A.CreateInstance("Send.Send");
29????????????Form?F?=?(Form)O;
30????????????F.Show();
31????????}
32????}
33}
34
代碼完成后,將Fanshe設(shè)為啟動(dòng)項(xiàng)并運(yùn)行,點(diǎn)擊button,調(diào)出outlook,界面如下:
?
這個(gè)簡單的例子就完成了,里面使用了反射的很少一部分內(nèi)容,但也可以幫助理解反射機(jī)制。
?四、反射的應(yīng)用要點(diǎn)
1.現(xiàn)實(shí)應(yīng)用程序中很少有應(yīng)用程序需要使用反射類型?
2.使用反射動(dòng)態(tài)綁定需要犧牲性能?
反射的性能損失主要來源于比較類型、遍歷成員、調(diào)用成員三種情形,其中比較類型耗時(shí)最小,調(diào)用成員耗時(shí)最多,所以盡量減少采用成員動(dòng)態(tài)調(diào)用等反射方式可以提高應(yīng)用程序性能。除此之外,采取后期綁定、避免將反射方法放到循環(huán)內(nèi)產(chǎn)生放大效應(yīng)等辦法均可提升反射性能。
3.有些元數(shù)據(jù)信息是不能通過反射獲取的?
某些反射類型是專門為那些clr?開發(fā)編譯器的開發(fā)使用的,所以你要意識(shí)到不是所有的反射類型都是適合每個(gè)人的。?程序下載:反射掉COM實(shí)例
轉(zhuǎn)載于:https://www.cnblogs.com/salonliudong/archive/2007/10/10/919719.html
總結(jié)
- 上一篇: 熊猫烧香源代码(转载)
- 下一篇: 我的CSS学习笔记