本節討論如何將源代碼文件轉換成能夠部署的文件。先看下面這個簡單的示例:編程
建立文本文件Program.txt,打開記事本鍵入以下代碼編程語言
public class Program { static void Main() { System.Console.WriteLine("Hello"); System.Console.ReadLine(); } }
在命令行執行如下命令:工具
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /out:Program.exe /t:exe /r:MSCorLib.dll Program.cs
執行結果以下:post
命令說明:
ui
MSCorLib.dll是特殊文件,它包含全部核心類型。因爲這些類型使用頻繁,以致於C#編譯器會自動引用MSCorLib.dll程序集,也就是說,上述命令中的/r:MSCorLib.dll能夠省略。又由於/out:Program.exe和/t:exe開關是C#編譯器的默認設定,因此上述命名能夠繼續簡化爲C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe Program.cs
spa
步驟3中的命令執行完畢後,會在相應路徑下生成可執行文件Program.exe,雙擊該可執行文件,結果以下:.net
響應文件是包含一組編譯器命令行開關的文本文件,執行csc.exe時,編譯器打開響應文件,使用其中包含的全部開關。.NET Framework安裝時會在%SystemRoot%\Microsoft.NET\Framework(64)\vX.X.X目錄中安裝默認全局CSC.rsp文件(X.X.X是安裝的.NET Framework版本號),全局CSC.rsp文件引用了列出的全部程序集,因此沒必要使用C#編譯器的/reference開關顯示引用這些程序集。命令行
元數據是由幾個表構成的二進制數據塊。分別是定義表、引用表和清單表。編譯器在編譯源代碼時,代碼定義的任何項都會在定義表中建立一個記錄。經常使用的元數據定義表以下:code
元數據定義表名稱 | 說明 |
---|---|
ModuleDef | 包含對模塊進行標識的一個記錄項。該記錄項包含模塊文件名和擴展名,以及模塊版本ID |
TypeDef | 記錄模塊中定義的類型在。包含類型的名稱、基類型、一些標誌和索引,這些索引指向MethodDef、FieldDef、PropertyDef、EventDef中的成員 |
MethodDef | 記錄模塊中定義的方法 |
FieldDef | 記錄模塊中定義的字段 |
ParamDef | 記錄模塊中定義的參數 |
PropertyDef | 記錄模塊中定義的屬性 |
EventDef | 記錄模塊中定義的事件 |
此外,編譯器還會檢測源代碼引用的類型、字段、方法、屬性和事件,並建立相應的引用表,它們記錄了引用的內容。regexp
引用表名稱 | 說明 |
---|---|
AssemblyRef | 記錄模塊引用的每一個程序集 |
ModuleRef | 記錄該模塊所引用的類型的每一個PE模塊 |
TypeRef | 記錄模塊引用的每一個類型 |
MemberRef | 記錄模塊引用的每一個成員 |
要查看元數據的相關內容,可使用微軟提供的IL反彙編工具ILDasm.exe檢查託管PE文件中的元數據,所在目錄:
C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools
使用ILDasm.exe打開上一節中的Program.exe程序集,選擇視圖|元信息|顯示!,隨後會顯示以下信息:
從元信息文件中咱們大體能夠看出Program.exe中包含名爲Program的TypeDef,這是一個公共類,從System.Object類派生,Program類型還定義了兩個方法:Main和.ctor(構造器)。
程序集是一個或多個類型定義文件及資源文件的集合。程序集中包含一個清單文件,主要包含做爲程序集組成部分的文件名稱、程序集版本、語言文化等描述性內容。CLR操做程序集,首先加載包含清單元數據表的文件,在根據清單來獲取程序集中的其餘文件的名稱。
爲何要引入程序集的概念?
由於使用程序集,可重用類型的邏輯表示與物理表示能夠分開。
使用多文件程序集的理由:
清單元數據表簡介:
清單元數據表名稱 | 說明 |
---|---|
AssemblyRef | 主要包含程序集名稱、版本、語言文化等內容 |
FileDef | 記錄程序集中每一個PE文件和資源文件,若程序集只包含模塊自己,不包含其餘模塊和資源文件,FileDef表將無數據 |
ManifestResourceDef | 記錄程序集中包含的每一個資源的名稱、標誌以及FileDef表中的一個索引 |
ExportedTpyesDef | 記錄從程序集的全部PE模塊中導出的每一個public類型 |
下面,咱們將經過一個示例來講明如何生成多文件程序集。
首先準備兩個源代碼文件
CommonTypes.cs
public class CommonTypes { public static void Main() { System.Console.WriteLine("Hello,This is CommonTypes"); System.Console.ReadLine(); } }
UncommonTypes.cs
public class UncommonTypes { public static void Main() { System.Console.WriteLine("Hello,This is UncommonTypes"); System.Console.ReadLine(); } }
將UncommonTypes編譯到一個單獨的模塊中,生成文件UncommonTypes.netmodule
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:module UncommonTypes.cs
將CommonTypes編譯到另外一個模塊,該模塊將成爲程序集清單的宿主,由於這些類型會常常使用。生成文件MultiFileLibrary.dll
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /out:MultiFileLibrary.dll /t:library /addmodule:UncommonTypes.netmodule CommonTypes.cs
使用ILDasm.exe工具檢查元數據清單表,以下圖可知程序集文件確實包含了對UncommonTypes.netmodule文件類型的引用。
當有項目引用MultiFileLibrary.dll時,編譯器會在搜索外部類型時加載MultiFileLibrary.dll以及FileDef表中列出的全部文件,也就是說,若是刪除UncommonTypes.netmodule文件,編譯時會報錯
CSC.exe生成PE文件程序集時,會在PE文件中嵌入標準的Win32版本資源。可查看文件屬性來檢查該資源。
版本號格式 | major(主版本號) | minor(次版本號) | build(內部版本號) | revision(修訂號) |
---|---|---|---|---|
示例 | 2 | 5 | 719 | 2 |