C#OOP之十三 組件、程序集與反射
視頻:https://edu.csdn.net/course/detail/27107
組件
組件技術是軟件領域一項非常大的成就。組件技術像搭積木游戲一樣,在搭積木時,我們知道并不是任何的兩個積木都可以組合,能組合的積木之間必定存在可以銜接的接口,同時,已經搭好的積木可以作為一個整體的大積木,被用來與其他積木組合。
在軟件領域,這些“積木”模型有微軟的COM,Sun的JavaBean、.Net的程序集等。
組件可以提高子程序的重用性和靈活性,并便于子程序的發布。也可以節省開發時間,提高程序的可靠性。
例如,Shapes類包含代表圓、三角形或其他圖形的對象。它的方法可用于計算圖形面積或執行圖形的其他操作。許多程序都要使用Shape類,完成如下功能:加色/繪圖程序、Visio/PPT/Word畫圖、建筑/施工設計、CAD、游戲及其他程序。
如果把Shapes設計成組件,僅定義一次,被在多個程序重用性,豈不美哉?(注意:不是在多個程序中Ctrl+C、Ctrl+V該類,這就太代碼工人了。)
在.Net編程模型中,我們使用程序集來實現組件技術的使用。
程序集
對于.Net來講,無論C#、VB、J#那種語言的應用程序編譯的最終結果都是一個程序集。編譯而成的程序集包括我們提到的Exe文件或DLL文件。.Net編譯生成的Exe文件和常規我們見的二進制可執行文件(exe文件,比如說QQ.exe)是不一樣的,它是由中間語言(IL)組成的可執行文件,必須由CLR來執行。
程序集具有以下特點:
·????????????????程序集作為 .exe 或 .dll 文件實現。
·????????????????通過將程序集放在全局程序集緩存中,可在多個應用程序之間共享程序集。
·????????????????要將程序集包含在全局程序集緩存中,必須對程序集進行強命名。
·????????????????程序集僅在需要時才加載到內存中。
·????????????????可以使用反射以編程方式獲取關于程序集的信息。
創建與使用程序集
第1步:建立控制臺項目,給項目改名為“CalcShapes”,如下圖:
第3步:查看解決方案,并修改Shapes類庫項目中的“Class1.cs”名為“Circle.cs”
第4步:編寫Circle類的代碼:
usingSystem; usingSystem.Collections.Generic; usingSystem.Text; namespace Shapes { public classCircle { double radius; public doubleRadius { get{ return radius; } set{ radius = value; } } public Circle() { radius = 0; } public Circle(doublegivenRadius) { radius = givenRadius; } public doublegetArea() { returnSystem.Math.PI * (radius * radius); } } }
第5步:在控制臺程序使用Shapes項目中的程序集,在CalcShapes項目的“引用”上右鍵單擊“添加引用”,然后彈出下面的對話框,選擇“項目”選項卡,選擇“Shapes”項目,然后點擊“確定”按鈕即可。
第6步:在控制臺程序中編寫代碼,并查看運行效果;
usingSystem; usingSystem.Collections.Generic; usingSystem.Text; usingShapes; //1.引用命名空間; namespaceCalcShapes { class Program { static voidMain(string[]args) { Circlecircle1 = new Circle(); circle1.Radius = 3.3; //設置圓周率 Console.WriteLine(circle1.getArea().ToString()); //現實圓面積 } } }
項目1:使用Winform來添加Shapes類引用
項目背景:針對我們已經寫好的程序集文件,方便我們在以后在各種程序中使用,所以,我們應該從各個方面將該組件淋漓盡致使用的“壓榨干凈”。在上述基礎上,添加新項目
解決方案:學習添加Winform項目
步驟1:添加Winform新項目到剛才的項目,如下圖:
步驟4:編寫代碼:
usingSystem; usingSystem.Collections.Generic; usingSystem.ComponentModel; usingSystem.Data; usingSystem.Drawing; usingSystem.Text; usingSystem.Windows.Forms; usingShapes; //1.引用命名空間 namespaceWinCalc { public partialclassForm1 : Form { public Form1() { InitializeComponent(); } private voidbutton1_Click(object sender,EventArgs e) { doubleradious = 0.0; Circlecircle1 = new Circle(); circle1.Radius = Convert.ToDouble(radious); MessageBox.Show("圓的面積為:" +circle1.getArea().ToString()); } } }
步驟5:設置WinCalc為啟動項目,如下圖,然后運行(F5):
步驟6:出現運行界面,輸入半徑,如下圖:
思考與擴充,在.Net中程序集組件引用的本質是多加幾個類庫項目,而是引用的其中的核心組件是什么?
請注意添加引用的本質是類庫項目所對應的程序集文件,如Shapes\bin\DebugShapes.dll文件。
【擴充在VB下使用C#的dll文件】
1.????? 界面設計省略同C#
2.代買比較痛苦:
PublicClass Form1 Private Sub Button1_Click(ByVal sender AsSystem.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim circle As Shapes.Circle circle = New Shapes.Circle() circle.Radius = 3.3 MessageBox.Show("VB圓面積" +circle.getArea().ToString()) End Sub End Class
2.????? 效果如下:
深入研究程序集
對于可執行的程序集來講,包含五部分的信息:
n???????PE32頭
這是標準的Windows可執行文件頭,它可以引導操作系統對此文件進行執行。二進制的可執行文件也必須有這個頭操作系統才能執行。PE頭里包含了標識文件類型的信息:Exe或Dll;除此之外里面還包括其生成時間以及入口方法地址(Main())等。操作系統可以通過讀取這個頭將托管模塊加載到內存中然后調用CLR從入口方法開始執行。
n???????元數據
元數據是托管模塊中最重要的數據。元數據用來表述托管模塊中包含的類型信息,這些信息包括類、接口、方法、字段、屬性、事件等代碼元素的定義信息。每個程序集都包含有元數據表,元數據表通常有兩種,一種是表述代碼中的類型或成員的列表;另外一種是表述源代碼中引用的類型和成員的表。在模塊或程序集中定義和引用的每個類型和成員都將在元數據中進行說明。當執行程序時,運行庫將加載元數據,并可以通過它來發現有關代碼的類、成員、繼承等信息。
n???????中間語言
.Net編譯器將編程語言的源代碼編譯后生成的中間語言代碼,在執行時,CLR將這些中間語言代碼編譯成CLR執行。
n???????資源
資源是指程序在運行時所需要的資源,包括圖片、字符串等。在默認情況下,一個程序集可以包含資源也可以不包含資源。如果程序集包含資源,那么程序集中會有一個叫做資源清單的結構專門來描述和連接這些資源文件,公共語言運行庫在運行時會管理或加載這些資源文件。
n???????程序集清單
程序集清單包含描述該程序集中各元素彼此如何關聯的數據集合。這些數據包括:程序集名稱、版本號、區域性、程序集中文件所有文件的列表、類型引用信息、有關被引用程序集的信息等。其中微軟規定的前四項(程序集名稱、版本號、區域性和強名稱信息)構成了程序集的標識。查看.Net創建的任何項目擬都會發現一個叫“AssemblyInfo”的文件,這個文件就是用來設置程序集清單的,一般在創建文件時會被自動生成。
反射及其使用
提到反射,首先我們會想到中學物理,光的反射是成像的基礎。如果沒有光的反射,你將看不到任何東西。如果沒有反射,你也不能照鏡子,就算你再帥再靚,你也不知道。
對于物體來說,你可以直接查看該物體,也可以通過鏡子來查看該物體。這些概念和軟件技術中反射的概念很相似。在軟件技術中,反射代表一種方法,一種通過間接途徑來查看和訪問程序集中元素的方法。
反射本質
C#項目在編譯后生成程序集,而程序集通過記錄了代碼中的所有類型。假如說,我們目前有某個組件的程序集,而沒有源代碼,我們能不能通過一種機制從程序集中取出各種類型進行操作呢?答案是肯定的,在.Net中可以通過反射機制從程序中提取任何存在的類型,包括類、結構、委托、接口和枚舉等,提取出類型后,利用反射機制我們甚至可以重新生成這些類型的對象,然后使用這些類型的成員,包括方法、屬性、事件、構造方法等。在一般情況下,我們可以使用反射來執行以下任務:
n????????獲取程序集中有關公共類型及其公共成員的信息
n????????了解代碼所在的模塊和程序集
n????????調用程序集中類型對象公共屬性或方法
要使用反射操作某個程序集中的類型,基本分為兩步走:
1.??????加載要反射的程序集;
2.??????然后通過Type類的方法對程序集中的類型進行枚舉或調用。
因為對非公共信息的訪問將帶來安全風險,所以.Net反射機制在默認情況下只能對程序集中的公共類型的信息或成員進行反射。
使用反射
在使用反射之前,我們首先需要加載程序集。需要使用System.Reflection命名空間下的Assembly類的Load方法或LoadFrom方法。這兩個方法都是靜態方法:
Assembly.Load(String 程序集名稱)
例如:Assembly assA=Assembly.Load(“Shapes”);
Assembly.LoadFrom(String? 程序集路徑)
例如:Assembly?assB=Assembly.LoadFrom(@”F:\MyShapes\bin\Debug\MyShaps.dll”)
接下來,通過Assembly的GetType和GetTypes方法來獲得加載程序集的類型了。前者只能獲得程序集里一個類型,后者可以獲得程序集里所有類型,原型如下:
public Type??? GetType(string name) //根據類名獲得該類型
public Type[]? GetTypes()??//獲得程序集的所有類型
一旦獲得程序集中的類型,就可以重建類型對應的對象。有關Type類的常用方法如下:
Type方法
返回類型
操作說明
GetMethod/GetMethods
MethodInfo
使用MethodInfo對象封裝的方法名稱、返回類型、參數、訪問修飾符等
GetField/GetFields
FieldInfo
使用FieldInfo封裝類型的字段名稱、訪問修飾符等
GetEvent/GetEvents
EventInfo
使用EventInfo封裝類型的字段名稱、事件處理程序、數據類型、自定義屬性、聲明類型和反射類型等
GetProperty/GetProperties
PropertyInfo
使用PropertyInfo封裝屬性的名稱、數據類型、聲明類型等
GetConstructor/GetConstructors
ConstructorInfo
使用ConstrucorInfo封裝構造方法的名稱、參數、訪問修飾符等信息
小結:
在本章中,我們主要學習了:
u??????組件的歷史和應用
u??????.Net中的組件技術
u??????反射技術的使用
u??????序列化
英語詞匯:
英文???????????? 全文???????????????????????????????????????? 中文
Attribute?????????????????????????????????????????? 屬性
Positional???????????????????????????????????????????????? 狀態的
Element??????????????????????????????????????????? 元素
Description????????????????????????????????????????????? 描述
Temperature??????????????????????????????????????????? 溫度
Fahrenheit?????????????????????????????????????????????? 華氏溫度
Service??????????????????????????????????????????????????? 服務
Import???????????????????????????????????????????????????? 導入
Inherited?????????????????????????????????????????? 繼承的
All??????????????????????????????????????????????????? 所有的
Assembly??????????????????????????????????????????????? 裝配、集合、組件
Module??????????????????????????????????????????? 模塊
Struct????????????????????????????????????????????????????? 結構
Specify???????????????????????????????????????????? 指定
游戲者
練習項目:
1.試將以前我們寫的計算器的計算類生成.dll程序集,供其他地方使用。
.NET C#
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。