版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、會計學1 泛型和反射泛型和反射 數(shù)據(jù)的抽象:數(shù)據(jù)的抽象: int MAX(int a,int b) return ab?a:b; double MAX1(double a,double b) return ab?a:b; int MAX(int a,int b) return ab?a:b; double MAX(double a,double b) return ab?a:b; 重載重載 數(shù)據(jù)類型的抽象:數(shù)據(jù)類型的抽象: T MAX(T a,T b) return ab?a:b; 泛型泛型 int、double數(shù)據(jù)數(shù)據(jù) 第第1頁頁/共共56頁頁 通常先聲明泛型,然后通過類型實例化來使用泛通常
2、先聲明泛型,然后通過類型實例化來使用泛 型。定義泛型的語法格式如下:型。定義泛型的語法格式如下: 訪問修飾符訪問修飾符返回類型返回類型 泛型名稱泛型名稱 其中,其中,“泛型名稱泛型名稱”要符合標識符的定義。尖括要符合標識符的定義。尖括 號表示類型參數(shù)列表,可以包含一個或多個類型參數(shù)號表示類型參數(shù)列表,可以包含一個或多個類型參數(shù) ,如,如。 7.1.2 7.1.2 泛型的聲明和使用泛型的聲明和使用 第第2頁頁/共共56頁頁 C#中常用的泛型有泛型類和泛型方法,例如:中常用的泛型有泛型類和泛型方法,例如: class Stack/聲明泛型類聲明泛型類 T dataMaxSize; int top;
3、 void swap(ref T a,ref T b)/定義泛型方法定義泛型方法 T tmp = a; a = b; b = tmp; 第第3頁頁/共共56頁頁 【例例7.1】 分析以下程序的執(zhí)行結果。分析以下程序的執(zhí)行結果。 using System; namespace proj7_1 class Student /學生類學生類 int sno; /學號學號 string sname; /姓名姓名 public Student() public Student(int no, string name) sno = no; sname = name; public void Dispstud
4、ent()/輸出學生對象輸出學生對象 Console.Write(0:1 ,sno,sname); 第第4頁頁/共共56頁頁 class Teacher /教師類教師類 int tno; /編號編號 string tname; /姓名姓名 public Teacher() public Teacher(int no, string name) tno = no; tname = name; public void Dispteacher()/輸出教師對象輸出教師對象 Console.Write(0:1 , tno, tname); 第第5頁頁/共共56頁頁 class Stack/聲明棧泛型類
5、聲明棧泛型類 int maxsize;/棧中元素最多棧中元素最多 個數(shù)個數(shù) T data;/存放棧中存放棧中T類類 型的元素型的元素 int top;/棧頂指針棧頂指針 public Stack()/構造函數(shù)構造函數(shù) maxsize = 10; data = new Tmaxsize; top = -1; public bool StackEmpty()/判斷??辗椒ㄅ袛鄺?辗椒?return top = -1; public bool Push(T e)/元素元素e進棧方法進棧方法 if (top = maxsize - 1)/棧滿返回棧滿返回false return false; top+
6、; datatop = e; return true; 第第6頁頁/共共56頁頁 public bool Pop(ref T e)/元素出棧方元素出棧方 法法 if (top = -1)/??辗祷貤?辗祷豧alse return false; e = datatop; top-; return true; 第第7頁頁/共共56頁頁 class Program static void Main(string args) /-整數(shù)棧操作整數(shù)棧操作- int e = 0; Stack s1 = new Stack(); /定義整數(shù)棧定義整數(shù)棧 s1.Push(1); /進棧進棧3個整個整 數(shù)數(shù) s1
7、.Push(2); s1.Push(3); Console.Write(整數(shù)棧出棧次序:整數(shù)棧出棧次序:); while (!s1.StackEmpty()/棧不空時出棧棧不空時出棧 元素元素 s1.Pop(ref e); Console.Write(0 , e); Console.WriteLine(); 第第8頁頁/共共56頁頁 /-實數(shù)棧操作實數(shù)棧操作- double d= 0; Stack s2 = new Stack();/定義實數(shù)棧定義實數(shù)棧 s2.Push(2.5);/進進 棧棧3個實數(shù)個實數(shù) s2.Push(3.8); s2.Push(5.9); Console.Write(實
8、數(shù)棧出棧次序:實數(shù)棧出棧次序:); while (!s2.StackEmpty()/棧不空時出棧棧不空時出棧 元素元素 s2.Pop(ref d); Console.Write(0 , d); Console.WriteLine(); 第第9頁頁/共共56頁頁 /-學生對象棧操作學生對象棧操作- Student st =new Student(); Stack s3 = new Stack();/定義學生棧定義學生棧 s3.Push(new Student(1,Student1);/進棧進棧3個學生個學生 對象對象 s3.Push(new Student(2,Student2); s3.Pus
9、h(new Student(3,Student3); Console.Write(學生對象棧出棧次序:學生對象棧出棧次序:); while (!s3.StackEmpty()/棧不空時出棧不空時出 棧元素棧元素 s3.Pop(ref st); st.Dispstudent(); Console.WriteLine(); 第第10頁頁/共共56頁頁 /-教師對象棧操作教師對象棧操作- Teacher te = new Teacher(); Stack s4 = new Stack();/定義教師棧定義教師棧 s4.Push(new Teacher(1, Teacher1); /進棧進棧3個教個教
10、 師對象師對象 s4.Push(new Teacher(2, Teacher2); s4.Push(new Teacher(3, Teacher3); Console.Write(教師對象棧出棧次序:教師對象棧出棧次序:); while (!s4.StackEmpty()/棧棧 不空時出棧元素不空時出棧元素 s4.Pop(ref te); te.Dispteacher(); Console.WriteLine(); 第第11頁頁/共共56頁頁 本程序先聲明本程序先聲明Student和和Teacher兩個類,再聲明一個兩個類,再聲明一個 泛型棧泛型棧Stack,然后實例化為整數(shù)棧,然后實例化為整
11、數(shù)棧s1、實數(shù)棧、實數(shù)棧s2、學、學 生對象棧生對象棧s3和教師對象棧和教師對象棧s4,各自進棧,各自進棧3個元素后并出棧,個元素后并出棧, 程序執(zhí)行結果如圖程序執(zhí)行結果如圖7.2所示。所示。 第第12頁頁/共共56頁頁 7.1.3 7.1.3 泛型的泛型的MSILMSIL代碼分析代碼分析 與與.NET Framework同時發(fā)布的中間語言反匯編工具同時發(fā)布的中間語言反匯編工具 (ildasm.exe)可以加載任意的)可以加載任意的.NET程序集并分析它的內程序集并分析它的內 容,包括關聯(lián)的清單、容,包括關聯(lián)的清單、MSIL代碼和類型元數(shù)據(jù)。代碼和類型元數(shù)據(jù)。 第第13頁頁/共共56頁頁 在命
12、令行方式下進入在命令行方式下進入ildasm.exe所在的文件夾,鍵入所在的文件夾,鍵入 ildasm命令,運行該程序,出現(xiàn)一個命令,運行該程序,出現(xiàn)一個“IL DASM”對話框對話框 ,選擇,選擇“文件文件|打開打開”命令。命令。 選擇例選擇例7.1的程序的程序proj7-1.exe(位于(位于“D:C#程序程序 ch7proj7-1proj7-1binDebug”文件夾中),便以樹狀圖文件夾中),便以樹狀圖 展示該程序集的結構,展開所有項的結果如圖展示該程序集的結構,展開所有項的結果如圖7.3所示。所示。 第第14頁頁/共共56頁頁 第第15頁頁/共共56頁頁 從例從例7.1程序的中間語言
13、代碼中可以看到如下要點。程序的中間語言代碼中可以看到如下要點。 1. 編譯方式編譯方式 第一輪編譯時,編譯器只為第一輪編譯時,編譯器只為Stack產(chǎn)生產(chǎn)生“泛型版泛型版” 的的IL代碼與元數(shù)據(jù),并不進行泛型的實例化,代碼與元數(shù)據(jù),并不進行泛型的實例化,T在中間只在中間只 充當占位符。例如,在充當占位符。例如,在Stack的構造函數(shù)中占位符顯示的構造函數(shù)中占位符顯示 為為。 在在JIT編譯時,當編譯時,當JIT編譯器第一次遇到編譯器第一次遇到Stack時時 ,將用,將用int替換替換“范型版范型版”IL代碼與元數(shù)據(jù)中的代碼與元數(shù)據(jù)中的T,即進行,即進行 泛型類型的實例化。例如,泛型類型的實例化。
14、例如,Main函數(shù)中顯示的函數(shù)中顯示的。 第第16頁頁/共共56頁頁 2. 2. 引用類型作為參數(shù)和值類型作為參數(shù)引用類型作為參數(shù)和值類型作為參數(shù) CLR為為所有類型參數(shù)為所有類型參數(shù)為“引用類型引用類型”的泛型類型產(chǎn)的泛型類型產(chǎn) 生同一份代碼生同一份代碼;但是如果;但是如果類型參數(shù)為類型參數(shù)為“值類型值類型”,對每一,對每一 個不同的個不同的“值類型值類型”,CLR將為其產(chǎn)生一份獨立的代碼將為其產(chǎn)生一份獨立的代碼, 這里的這里的s3和和s4的的idloc.s的地址相同,都是的地址相同,都是CS$4$0000。 因為實例化一個引用類型的泛型,它在內存中分配的因為實例化一個引用類型的泛型,它在內
15、存中分配的 大小是一樣的,但是當實例化一個值類型的時候,在內存大小是一樣的,但是當實例化一個值類型的時候,在內存 中分配的大小是不一樣的。這樣做的目的是盡可能減小代中分配的大小是不一樣的。這樣做的目的是盡可能減小代 碼量。碼量。 第第17頁頁/共共56頁頁 7.1.4 7.1.4 類型參數(shù)的約束類型參數(shù)的約束 在泛型類型或方法定義中,類型參數(shù)是在實例化泛型類在泛型類型或方法定義中,類型參數(shù)是在實例化泛型類 型的變量時指定的特定類型的占位符。型的變量時指定的特定類型的占位符。 那么,類型參數(shù)是不是任何類型呢?結論是否定的。那么,類型參數(shù)是不是任何類型呢?結論是否定的。 第第18頁頁/共共56頁頁
16、 例如,聲明以下泛型類型:例如,聲明以下泛型類型: class MyGType static public bool LessThan(T1 obj1, T2 obj2) return obj1 obj2; 在編譯時,系統(tǒng)指出在編譯時,系統(tǒng)指出“運算符運算符無法應用于無法應用于T1和和T2類型類型 的操作數(shù)的操作數(shù)”的錯誤。如果它是正確的,在實例化為的錯誤。如果它是正確的,在實例化為 MyGType時,一個整數(shù)和一個字符串怎么比較時,一個整數(shù)和一個字符串怎么比較 呢?甚至在實例化為呢?甚至在實例化為MyGType時,一個整數(shù)時,一個整數(shù) 和一個對象怎么比較呢?和一個對象怎么比較呢? 第第19頁
17、頁/共共56頁頁 為了解決這個問題,為了解決這個問題,C#提出了類型參數(shù)的約束的概念。提出了類型參數(shù)的約束的概念。 通過約束檢查泛型列表中的某個項以確定它是否有效。通過約束檢查泛型列表中的某個項以確定它是否有效。 例如,約束告訴編譯器:僅此類型的對象或從此類型派例如,約束告訴編譯器:僅此類型的對象或從此類型派 生的對象才可用作類型參數(shù)。一旦編譯器有了這個保證,它生的對象才可用作類型參數(shù)。一旦編譯器有了這個保證,它 就能夠允許在泛型類中調用該類型的方法。就能夠允許在泛型類中調用該類型的方法。 約束是使用上下文關鍵字約束是使用上下文關鍵字 where 應用的。應用的。where子句的一子句的一 般
18、格式如下:般格式如下: where 類型參數(shù):約束類型參數(shù):約束1,約束,約束2, 第第20頁頁/共共56頁頁 例如,以下泛型有例如,以下泛型有3個類型參數(shù),個類型參數(shù),T1是未綁定的(沒有是未綁定的(沒有 約束),約束),T2只有只有MyClass1類型或從它派生的類或類型或從它派生的類或 MyClass2類型或從它派生的類才能用作類型實參,類型或從它派生的類才能用作類型實參,T3只有只有 MyClass3類型或從它派生的類才能用作類型實參:類型或從它派生的類才能用作類型實參: class MyClass where T2:MyClass1,MyClass2 T3:MyClass3 這樣在對
19、類型參數(shù)的類型種類施加限制后,如果使用這樣在對類型參數(shù)的類型種類施加限制后,如果使用 該泛型的代碼嘗試使用某個約束所不允許的類型來實例化該泛型的代碼嘗試使用某個約束所不允許的類型來實例化 類,則會產(chǎn)生編譯時錯誤。類,則會產(chǎn)生編譯時錯誤。 第第21頁頁/共共56頁頁 7.1.5 7.1.5 泛型的繼承泛型的繼承 C#除了可以單獨聲明泛型類型外,也可以在基類中除了可以單獨聲明泛型類型外,也可以在基類中 包含泛型類型的聲明。包含泛型類型的聲明。 但基類如果是泛型類,它的類型要么已實例化,要但基類如果是泛型類,它的類型要么已實例化,要 么來源于子類(同樣是泛型類型)聲明的類型參數(shù)。么來源于子類(同樣是
20、泛型類型)聲明的類型參數(shù)。 第第22頁頁/共共56頁頁 例如,若聲明了如下泛型:例如,若聲明了如下泛型: class C 則以下聲明是正確的:則以下聲明是正確的: class D:C /繼承的類型已實例化繼承的類型已實例化 class E:C/E類型為類型為C類型提供了類型提供了U、V,即來,即來 源于子類源于子類 class F:C /F類型繼承于類型繼承于C,可看成,可看成F繼繼 承一個非泛型的類承一個非泛型的類 第第23頁頁/共共56頁頁 而以下聲明是錯誤的:而以下聲明是錯誤的: class G:C /因為因為G類型不是泛型,類型不是泛型,C是泛型,是泛型,G無法給無法給C提供泛提供泛
21、型的實例化型的實例化 第第24頁頁/共共56頁頁 7.1.6 7.1.6 泛型接口和委托泛型接口和委托 1. 泛型接口泛型接口 與泛型繼承類似,泛型接口的類型參數(shù)要么已實例與泛型繼承類似,泛型接口的類型參數(shù)要么已實例 化,要么來源于實現(xiàn)類聲明的類型參數(shù)?;?,要么來源于實現(xiàn)類聲明的類型參數(shù)。 第第25頁頁/共共56頁頁 2. 泛型委托泛型委托 泛型委托支持在委托返回值和參數(shù)上應用參數(shù)類型,泛型委托支持在委托返回值和參數(shù)上應用參數(shù)類型, 這些參數(shù)類型同樣可以附帶合法的約束。這些參數(shù)類型同樣可以附帶合法的約束。 第第26頁頁/共共56頁頁 例如:例如: delegate bool MyDelegat
22、e(T value); class MyClass static bool method1(int i) static bool method2(string s) static void Main() MyDelegate p2 = method2; MyDelegate p1 = new MyDelegate( method1); 第第27頁頁/共共56頁頁 反射是一種機制,通過這種機制可以知道一個未知類反射是一種機制,通過這種機制可以知道一個未知類 型的類型信息。型的類型信息。 例如有一個對象,它例如有一個對象,它不是我們定義的不是我們定義的,既可能是通過,既可能是通過 網(wǎng)絡捕捉到的,也
23、可能是使用泛型定義的,但我們網(wǎng)絡捕捉到的,也可能是使用泛型定義的,但我們想知道想知道 這個對象的類型信息,想知道這個對象有哪些方法或者屬這個對象的類型信息,想知道這個對象有哪些方法或者屬 性什么性什么的,甚至的,甚至想進一步調用這個對象的方法想進一步調用這個對象的方法。關鍵是現(xiàn)。關鍵是現(xiàn) 在只知道它是一個對象,不知道它的類型,自然不會知道在只知道它是一個對象,不知道它的類型,自然不會知道 它有哪些方法等信息,這時該怎么辦呢它有哪些方法等信息,這時該怎么辦呢? 7.2.1 7.2.1 反射概述反射概述 第第28頁頁/共共56頁頁 反射機制就是解決這么一個問題的,通過反射機制就是解決這么一個問題的
24、,通過反射機制就反射機制就 可以知道未知類型對象的類型信息可以知道未知類型對象的類型信息。 第第29頁頁/共共56頁頁 歸納歸納起來,反射在下列情況下很有用:起來,反射在下列情況下很有用: l 需要訪問程序元數(shù)據(jù)的屬性。需要訪問程序元數(shù)據(jù)的屬性。 l 檢查和實例化程序集中的類型。檢查和實例化程序集中的類型。 l 在運行時構建新類型。在運行時構建新類型。 l 執(zhí)行后期綁定,訪問在運行時創(chuàng)建的類型的方執(zhí)行后期綁定,訪問在運行時創(chuàng)建的類型的方 法。法。 第第30頁頁/共共56頁頁 1. Type類類 System.Reflection是反射的命名空間,而是反射的命名空間,而Type類類為為 Syst
25、em.Reflection功能的根,也是訪問元數(shù)據(jù)的主要方式功能的根,也是訪問元數(shù)據(jù)的主要方式 。 Type類表示類型聲明,包括類類型、接口類型、數(shù)組類表示類型聲明,包括類類型、接口類型、數(shù)組 類型、值類型、枚舉類型、類型參數(shù)、泛型類型定義,以類型、值類型、枚舉類型、類型參數(shù)、泛型類型定義,以 及開放或封閉構造的泛型類型。及開放或封閉構造的泛型類型。 7.2.2 7.2.2 反射中常用的類反射中常用的類 第第31頁頁/共共56頁頁 公共屬性公共屬性說明說明 IsAbstract獲取一個值,通過該值指示獲取一個值,通過該值指示Type是否為抽象的并且必須被重寫是否為抽象的并且必須被重寫 IsAr
26、ray獲取一個值,通過該值指示獲取一個值,通過該值指示Type是否為數(shù)組是否為數(shù)組 IsByRef獲取一個值,通過該值指示獲取一個值,通過該值指示Type是否由引用傳遞是否由引用傳遞 IsClass獲取一個值,通過該值指示獲取一個值,通過該值指示Type是否是一個類,即不是值類型或接口是否是一個類,即不是值類型或接口 IsInterface獲取一個值,通過該值指示獲取一個值,通過該值指示Type是否為接口,即不是類或值類型是否為接口,即不是類或值類型 IsSubclassOf確定當前確定當前Type表示的類是否是從指定的表示的類是否是從指定的Type表示的類派生的表示的類派生的 MakeArr
27、ayType返回一個表示當前類型的一維數(shù)組(下限為零)的返回一個表示當前類型的一維數(shù)組(下限為零)的Type對象對象 Module獲取在其中定義當前獲取在其中定義當前Type的模塊的模塊 Name獲取當前成員的名稱獲取當前成員的名稱 Namespace獲取獲取Type的命名空間的命名空間 ReflectedType獲取用于獲取該成員的類對象獲取用于獲取該成員的類對象 Type類的屬性類的屬性 第第32頁頁/共共56頁頁 方法方法說明說明 GetElementType當在派生類中重寫時,返回當前數(shù)組、指針或引用類型包含的或引用當在派生類中重寫時,返回當前數(shù)組、指針或引用類型包含的或引用 的對象的
28、的對象的Type GetEvent獲取由當前獲取由當前Type聲明或繼承的特定事件聲明或繼承的特定事件 GetEvents獲取由當前獲取由當前Type聲明或繼承的事件聲明或繼承的事件 GetField獲取當前獲取當前Type的特定字段的特定字段 GetFields獲取當前獲取當前Type的字段的字段 GetInterface獲取由當前獲取由當前Type實現(xiàn)或繼承的特定接口實現(xiàn)或繼承的特定接口 GetInterfaces當在派生類中重寫時,獲取由當前當在派生類中重寫時,獲取由當前Type實現(xiàn)或繼承的所有接口實現(xiàn)或繼承的所有接口 GetMember獲取當前獲取當前Type的指定成員的指定成員 Ge
29、tMembers獲取當前獲取當前Type的成員(包括屬性、方法、字段、事件等)的成員(包括屬性、方法、字段、事件等) GetMethod獲取當前獲取當前Type的特定方法的特定方法 GetMethods獲取當前獲取當前Type的方法的方法 GetProperties獲取當前獲取當前Type的屬性的屬性 GetProperty獲取當前獲取當前Type的特定屬性的特定屬性 InvokeMember使用指定的綁定約束并匹配指定的參數(shù)列表,調用指定成員使用指定的綁定約束并匹配指定的參數(shù)列表,調用指定成員 Type類的方法類的方法 第第33頁頁/共共56頁頁 歸納起來,得到一個歸納起來,得到一個Type
30、實例的三種方法如下:實例的三種方法如下: (1)使用)使用System.Object.GetType(),例如:例如: Person pe=new Person();/定義定義pe為為person類的一個對象類的一個對象 Type t=pe.GetType(); 這樣這樣t為為pe的的Type對象。對象。 (2)使用)使用System.Type.GetType()靜態(tài)方法,靜態(tài)方法,參數(shù)為參數(shù)為 類型的完全限定名。例如:類型的完全限定名。例如: Type t=Type.GetType(MyNs.Person); 其中,其中,MyNs.Person為為MyNs命名空間中的命名空間中的Person
31、類類 ,這樣,這樣t為該類的為該類的Type對象。對象。 第第34頁頁/共共56頁頁 (3)使用)使用typeof運算符運算符,例如:,例如: Type t=typeof(Person); 其中其中Person為一個類,這樣為一個類,這樣t為該類的為該類的Type對象。對象。 第第35頁頁/共共56頁頁 2. System.Reflection反射命名空間反射命名空間 System.Reflection反射命名空間包含提供加載類型、方反射命名空間包含提供加載類型、方 法和字段的有組織的視圖的類和接口,具有動態(tài)創(chuàng)建和調法和字段的有組織的視圖的類和接口,具有動態(tài)創(chuàng)建和調 用類型的功能。其中主要的類
32、及其功能如下:用類型的功能。其中主要的類及其功能如下: lAssembly類:類:通過它可以加載、了解和操作一個程序集。通過它可以加載、了解和操作一個程序集。 lAssemblyName類:類:通過它可以找到大量隱藏在程序集的身通過它可以找到大量隱藏在程序集的身 份中的信息,如版本信息、區(qū)域信息等。份中的信息,如版本信息、區(qū)域信息等。 lConstructorInfo類:類:用于發(fā)現(xiàn)構造函數(shù)及調用構造函數(shù)。通用于發(fā)現(xiàn)構造函數(shù)及調用構造函數(shù)。通 過對過對ConstructorInfo調用調用Invoke來創(chuàng)建對象,其中來創(chuàng)建對象,其中 ConstructorInfo是由是由Type對象的對象的G
33、etConstructors或或 GetConstructor方法返回的。方法返回的。 lEventInfo類:類:通過它可以找到事件的信息。通過它可以找到事件的信息。 第第36頁頁/共共56頁頁 lFieldInfo類:類:通過它可以找到字段的信息。通過它可以找到字段的信息。 lMethodInfo類:類:通過它可以找到方法的信息。通過它可以找到方法的信息。 lParameterInfo類:類:通過它可以找到參數(shù)的信息。通過它可以找到參數(shù)的信息。 lPropertyInfo類:類:通過它可以找到屬性的信息。通過它可以找到屬性的信息。 lMemberInfo類:類:它是一個抽象基類,為它是一個
34、抽象基類,為EventInfo、FieldInfo 、MethodInfo、PropertyInfo等類型定義了公共的行為。等類型定義了公共的行為。 lModule類:類:用來訪問帶有多文件程序集的給定模塊。用來訪問帶有多文件程序集的給定模塊。 lDefaultMemberAttribute類:類:定義某類型的成員,該成員是定義某類型的成員,該成員是 InvokeMember使用的默認成員。使用的默認成員。 第第37頁頁/共共56頁頁 公共屬性公共屬性說明說明 EntryPoint獲取此程序集的入口點獲取此程序集的入口點 FullName獲取程序集的顯示名稱獲取程序集的顯示名稱 Locatio
35、n獲取包含清單的已加載文件的路徑或位置獲取包含清單的已加載文件的路徑或位置 ManifestModule獲取包含當前程序集清單的模塊獲取包含當前程序集清單的模塊 其中其中重要的重要的Assembly類,它的常用屬性和常用方法如下。類,它的常用屬性和常用方法如下。 Assembly類的常用屬性類的常用屬性 第第38頁頁/共共56頁頁 方法方法說明說明 GetFiles獲取程序集清單文件表中的文件獲取程序集清單文件表中的文件 GetModule獲取此程序集中的指定模塊獲取此程序集中的指定模塊 GetModules獲取作為此程序集的一部分的所有模塊獲取作為此程序集的一部分的所有模塊 GetType獲
36、取表示指定類型的獲取表示指定類型的Type對象對象 GetTypes獲取此程序集中定義的類型獲取此程序集中定義的類型 LoadFile加載程序集文件的內容加載程序集文件的內容 LoadFrom在已知程序集的文件名或路徑等信息時加載程序集在已知程序集的文件名或路徑等信息時加載程序集 LoadModule加載此程序集的內部模塊加載此程序集的內部模塊 Assembly類的常用方法類的常用方法 第第39頁頁/共共56頁頁 1. 通過反射查看類型的成員信息通過反射查看類型的成員信息 查看類型信息的過程如下:查看類型信息的過程如下: (1)獲取指定類型的一個)獲取指定類型的一個Type對象或對象或Type
37、對象數(shù)組對象數(shù)組 。 (2)通過)通過Type類的許多方法來發(fā)現(xiàn)與該類型的成員類的許多方法來發(fā)現(xiàn)與該類型的成員 有關的信息。有關的信息。 7.2.3 7.2.3 反射的應用示例反射的應用示例 第第40頁頁/共共56頁頁 【例例7.3】 編寫一個程序,通過反射輸出編寫一個程序,通過反射輸出System.Object 類的方法、字段和構造函數(shù)的信息。類的方法、字段和構造函數(shù)的信息。 解:解:先通過先通過Type的的GetTypes()方法獲取方法獲取System.Object類類 的的Type對象對象t,然后用,然后用Type類的類的GetMethods()、GetFields() 、GetCon
38、structors()分別獲取分別獲取t對象的方法、字段和構造函對象的方法、字段和構造函 數(shù)信息并輸出。程序如下:數(shù)信息并輸出。程序如下: 第第41頁頁/共共56頁頁 using System; using System.Reflection; namespace proj7_3 class Program static void Main(string args) string classname = System.Object; Console.WriteLine(0類類,classname); Type t = Type.GetType(classname); MethodInfo m
39、= t.GetMethods(); Console.WriteLine( 0的方法個數(shù)的方法個數(shù):1, t.FullName, m.Length); 第第42頁頁/共共56頁頁 foreach(MethodInfo item in m) Console.WriteLine(t0 ,item.Name); FieldInfo f = t.GetFields(); Console.WriteLine( 0的字段個數(shù)的字段個數(shù):1, t.FullName, f.Length); foreach (FieldInfo item in f) Console.WriteLine(t0 , item.Nam
40、e); ConstructorInfo c = t.GetConstructors(); Console.WriteLine( 0的構造函數(shù)個數(shù)的構造函數(shù)個數(shù):1, t.FullName, c.Length); foreach (ConstructorInfo item in c) Console.WriteLine(t0 , item.Name); 程序執(zhí)行結果程序執(zhí)行結果 第第43頁頁/共共56頁頁 2. 通過反射調用未知類的某方法通過反射調用未知類的某方法 調用未知類的某方法的過程如下:調用未知類的某方法的過程如下: (1)假設一個未知類)假設一個未知類c屬于某個屬于某個DLL文件文件x
41、yz.dll,采,采 用用Assembly.LoadFrom(xyz.dll)加載該程序集。加載該程序集。 (2)調用)調用assembly.GetTypes()方法得到一個方法得到一個Type對對 象數(shù)組象數(shù)組t。 (3)通過)通過Type.GetConstructor()方法得到某個對象方法得到某個對象 的構造函數(shù)。的構造函數(shù)。 (4)通過)通過ConstructorInfo.Invoke()方法調用構造函方法調用構造函 數(shù)創(chuàng)建未知類的對象數(shù)創(chuàng)建未知類的對象s。 (5)通過對象)通過對象s調用某方法。調用某方法。 第第44頁頁/共共56頁頁 【例例7.4】 有一個項目有一個項目proj7_
42、4,通過添加代碼文件模板,通過添加代碼文件模板 向其中添加一個向其中添加一個Sport.cs文件,該文件的內容如下:文件,該文件的內容如下: using System; public abstract class Sport/體育運動類體育運動類 protected string name;/項項 目名目名 public abstract string GetDuration();/獲取比賽時間獲取比賽時間 public abstract string GetName();/獲取項目名獲取項目名 第第45頁頁/共共56頁頁 在命令行方式下使用以下命令生成在命令行方式下使用以下命令生成Sport
43、.dll文件:文件: Csc /target:library Sport.cs 第第46頁頁/共共56頁頁 同樣通過添加代碼文件模板向其中添加一個同樣通過添加代碼文件模板向其中添加一個SomeSports.cs 文件,該文件的內容如下:文件,該文件的內容如下: using System; public class Basketball : Sport public Basketball()/籃球類籃球類 name = 籃球籃球; public override string GetDuration() return 共共4節(jié)節(jié),每,每節(jié)節(jié)15分鐘分鐘; public override stri
44、ng GetName() return name; 第第47頁頁/共共56頁頁 public class Hockey : Sport/曲棍球類曲棍球類 public Hockey() name = 曲棍球曲棍球; public override string GetDuration() return 兩個半場,兩個半場,各各35分鐘分鐘; public override string GetName() return name; public class Football : Sport/足球類足球類 public Football() name = 足球足球; public overrid
45、e string GetDuration() return 兩個半場,兩個半場,各各45分鐘分鐘; public override string GetName() return name; 第第48頁頁/共共56頁頁 在命令行方式下使用以下命令生成在命令行方式下使用以下命令生成SomeSports.dll文件:文件: csc /target:library /reference:Sport.dll SomeSports.cs 這樣就生成兩個動態(tài)鏈接庫文件這樣就生成兩個動態(tài)鏈接庫文件Sport.dll和和 SomeSports.dll。現(xiàn)要在?,F(xiàn)要在Program類類Main中設計相應代碼,根中設計相應代碼,根 據(jù)用戶選擇的體育項目輸出相應的比賽時間。據(jù)用戶選擇的體育項目輸出相應的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度某公司電子商務事業(yè)部跨境電商營銷推廣合作協(xié)議2篇
- 2025版融創(chuàng)集團房地產(chǎn)合同檔案安全保護與保密要求3篇
- 二零二五年度外匯期貨居間經(jīng)紀業(yè)務合同修訂版4篇
- 2025版全新煤炭居間合作協(xié)議范本下載6篇
- 個性化勞動協(xié)議模板2024年版參考版B版
- 個性化咨詢顧問服務協(xié)議精簡版版
- 2025年配電工程進度款支付合同
- 2025年度新材料研發(fā)與產(chǎn)業(yè)化合作協(xié)議
- 二零二五年度內退員工離職補償及經(jīng)濟補償合同
- 二零二五年度品牌策劃與品牌維權服務合同2篇
- 2024年上海市第二十七屆初中物理競賽初賽試題及答案
- 信息技術部年終述職報告總結
- 高考滿分作文常見結構完全解讀
- 理光投影機pj k360功能介紹
- 六年級數(shù)學上冊100道口算題(全冊完整版)
- 八年級數(shù)學下冊《第十九章 一次函數(shù)》單元檢測卷帶答案-人教版
- 帕薩特B5維修手冊及帕薩特B5全車電路圖
- 系統(tǒng)解剖學考試重點筆記
- 小學五年級解方程應用題6
- 年月江西省南昌市某綜合樓工程造價指標及
- 作物栽培學課件棉花
評論
0/150
提交評論