——當我第一次聽到Microsoft .NET平台時,我就知道它将續寫微軟不敗的神話。(Jeffrey Richter)
這篇文章我很早很早之前就想寫了,本來是想把它作為我開博的第一篇的,但由于種種原因直到現在寫出來。本文不是用.NET平台和其餘平台(諸如Java)做比較,不去評論孰優孰劣。僅僅是作為一個.NET開發者,介紹一下我眼中的.NET。
.NET Framework包括公共語言運作時(Common Language Runtime,CLR)和架構類庫(Framework Class Library,FCL)。
CLR是.NET Framework 的基礎、核心,提供了包括記憶體管理、線程管理和遠端調用等核心服務。
FCL是一個基于面向對象的可重用類型集合,用于支援多種應用的快速開發,諸如ASP.NET Web應用、Windows Form應用、Web Service應用、Windows Presentation Foundation(WPF)應用等。
<a target="_blank" href="http://blog.51cto.com/attachment/201008/092235285.gif"></a>
圖1、.NET Framework(來自:MSDN)
.NET Framework提供一個托管執行環境、簡化開發和部署、整合了多種開發語言。CLR是.NET體系的基礎,所有的.NET代碼都運作在CLR之上,并且與FCL緊密結合,并由此建立基于.NET的Windows Forms、Web Forms和XML Web Services等應用程式。.NET Framework的下層是作業系統,上層是.NET的進階開發語言(C#、F#等)。
CLR(公共語言運作時,Common Language Runtime)和Java虛拟機一樣也是一個運作時環境,它負責資源管理(記憶體配置設定和垃圾收集),并保證應用和底層作業系統之間必要的分離。
CLR将監視形形色色的常見程式設計錯誤,許多年來這些錯誤一直是軟體故障的主要根源,其中包括:通路數組元素越界,通路未配置設定的記憶體空間,由于資料體積過大而導緻的記憶體溢出,等等。
可以使用 C# 語言編寫托管代碼,C# 語言提供了下列優點:
完全面向對象的設計。
非常強的類型安全。
很好地融合了 Visual Basic 的簡明性和 C++ 的強大功能。
垃圾回收。
類似于 C 和 C++ 的文法和關鍵字。
.NET Framework 類庫是一個由 Microsoft .NET Framework 中包含的類、接口和值類型組成的庫。該庫提供對系統功能的通路,是建立 .NET Framework 應用程式、元件和控件的基礎。為便于語言之間進行互動操作,.NET Framework 類型是符合 CLS 的,并是以可在任何程式設計語言中使用,隻要這種語言的編譯器符合公共語言規範 (CLS)。NET Framework 包括的類型執行下列功能:
表示基礎資料類型和異常。
封裝資料結構。
執行 I/O。
通路關于加載類型的資訊。
調用 .NET Framework 安全檢查。
提供資料通路、多用戶端 GUI 和伺服器控制的用戶端 GUI。
.NET上的程式從源碼到執行有以下幾個步驟(來自Jeffery Richter的《.NET架構程式設計》):
将源碼編譯為托管子產品;
将托管子產品組合為程式集;
加載公共語言運作時CLR;
執行程式集代碼。
這幾個過程我總結為下圖:
<a target="_blank" href="http://blog.51cto.com/attachment/201008/092444239.jpg"></a>
圖2、.NET上的程式運作
關于托管子產品與程式集的關系,我了解如下:
CLR實際上不和托管子產品打交道,它直接打交道的對象是程式集。程式集由一個或多個托管子產品及相關的資源檔案邏輯組成。其次,程式集是元件複用,以及實施安全政策和版本政策的最小機關。程式集中有一個托管子產品中包含清單(manifest)的資料塊,而清單僅僅也是一些中繼資料表的集合,但是這些表描述了組成程式集所有檔案中的公有導出類型,以及一些和程式集相關的資源檔案或資料檔案。如果程式集隻有一個托管子產品且沒有資源檔案,該程式集就是托管子產品。
由于CLR不直接和托管子產品打交道,是以預設情況下,編譯器會将産生的托管子產品轉換為一個程式集。隻有這樣程式才能夠運作。
托管子產品有下列部分組成:
PE32或PE32+表頭:标準PE檔案頭,類似于Common Object File Format頭。如果頭使用PE32格式,檔案可以運作在32位或64位的Windows當中。如果頭使用PE32+格式,檔案必須運作在64位 Windows當中。該頭還指名了檔案的類型:GUI、CUI或DLL,同時還包含了一個用來指明檔案何時建立的時間戳。對于隻包含IL代碼的子產品,PE32(+)中的大量資訊都會被忽略。對于包含本地CPU代碼的子產品,頭還包括本地CPU代碼的資訊。
CLR表頭:包含辨別托管子產品的一些資訊(可以被CLR或一些工具解析)。包括托管子產品所需要的CLR版本号、一些标記、托管子產品入口點方法(main方法)的MethodDef中繼資料标記、以及有關托管子產品的中繼資料(metadata)、資源(resources)、強命名(strong name)、标記(flags)、和其他一些意義不大的資訊的位置和大小。
中繼資料:每個托管子產品都包含一些中繼資料表。中繼資料表主要分兩種:一種用來描述代碼中定義的類型和成員。一種用來描述代碼中引用的類型和成員。
IL代碼:編譯器在編譯源代碼時産生的代碼。在運作時,CLR将IL編譯為本地CPU指令。
程式集是CLR操作的對象。程式集由一個或多個托管子產品及相關的資源檔案邏輯組成。在程式集包含的所有檔案中,有一個檔案用于儲存清單,清單是另外一組中繼資料表的集合,其中主要包含了程式集中的一部分檔案的名稱,另外清單檔案還描述了程式集的版本、語言文化、釋出者、公有導出類型、以及組成該程式集的所有檔案。CLR總是先加載包含清單中繼資料表的檔案,然後利用該清單來擷取程式集中的其它檔案。
使用程式集的原因有:
程式集允許我們分離可重用類型的邏輯表示和實體表示。
可以将類型分别實作在不同的檔案中,進而允許在網際網路環境中進行增量下載下傳。
可以按需向程式集中添加資源或資料檔案。
可以使我們建立的程式集包含一些用不同程式設計語言實作的類型。
總而言之,程式集是一個可重用、可實施版本政策和安全政策的單元。它允許我們将類型和資源劃分到不同的檔案中,這樣程式集的使用者便可以決定将哪些檔案打包一起部署。一旦CLR加載了程式集中包含清單的那個檔案,它就可以确定程式集中的其他檔案中哪些包含了程式正在引用的類型和資源。任何程式集的使用者僅需要知道包含了清單的檔案名。要生成一個程式集,我們必須選擇一個托管子產品作為清單的儲存者。
PS:以上僅為個人愚見,定有不當之處,歡迎指正!當中設計的很多概念也沒有深入,以及很多概念也沒有引出,如中繼資料沒有深入介紹、FCL也沒有一個系統的介紹、未介紹到應用程式域等等。當然要完成這些需要大量篇幅,以後會逐漸介紹。
本文轉自Saylor87 51CTO部落格,原文連結:http://blog.51cto.com/skynet/366034,如需轉載請自行聯系原作者