天天看點

C#、.NET Framework、CLR的關系

C#、.NET Framework、CLR的關系

很多人沒有将C#、.NET Framework(.NET架構)、CLR(Common Language

Runtime,公共語言運作庫)這三者之間的關系區厘清楚,認為其版本号是一一對應的。其實不然,.NET架構是一個獨立釋出的軟體包,其包含了CLR、類庫以及相關的語言編輯器等工具。C#代碼經過編譯之後在CLR環境中運作。由于.NET架構3.0/3.5其實是.NET2.0的擴充(隻是增加了一些新的程式集),是以.NET3.0/3.5的CLR版本還是2.0.而且.NET3.0其實隻擴充了WF、WPF、WCF、WCS等元件,并沒有提供新的C#編譯器,直到.NET3.5中才打包了C#3.0的編譯器。.NET4.0在3.0上針對WF、WCF進行了一些新功能增加,是以.NET架構、CLR和C#的版本之間的對應關系如下表所示:

也就是說,對于那些不涉及新程式集的C#3.0新特性(比如自動屬性、匿名屬性等)在.NET2.0的環境中也可以運作,CLR對這些特性是一無所知的。

1、C#是一種面向對象程式設計語言,是為開發.NET架構上的程式而設計的。

(1)C#是由C和C++衍生出來的,是以其可調用由 C/C++ 編寫的本機原生函數,同時不損失C/C++原有的強大的功能。

(2)C#所開發的程式源代碼并不是編譯成能夠直接在作業系統上執行的二進制本地代碼。它是被編譯成為中間代碼,然後通過.NET架構的虛拟機(即CLR)來執行。是以如果計算機上沒有安裝.Net架構,那麼程式将不能夠被執行。在執行的過程中,.Net架構會将中間代碼翻譯成為二進制機器碼,進而使它得到正确的運作。最終翻譯的二進制代碼将被存儲在一個緩沖區中。是以一旦程式使用了相同的代碼,那麼将會調用緩沖區中的版本。這樣如果一個.Net程式第二次被運作,那麼這種翻譯不需要進行第二次,速度會明顯加快。

2、.NET架構有三部分組成(如下圖):

1)CLR的介紹參考3

2)程式設計工具:涵蓋了編碼和調試需要的一切:包含:VisualStudio內建開發環境、.NET相容的編譯器(例如:C#、VB、JScript和托管的C++)、調試器、伺服器端改進(比如ASP.NET)

3)BCL(Base Class

Library,基類庫):是.NET架構使用的一個大的類庫,而且也可以在你的程式中使用。包括以下一些類。

1>通用基礎類:這些類提供了一組極為強大的工具,可以應用帶廣泛的程式設計任務中,比如字元串操作、安全和加密。

    2>集合類:這些類實作了清單、字典、散清單以及位數組。

    3>線程和同步類:這些類用于建立多線程程式。

    4>XML類,這些類用于建立、讀取以及操作XML文檔。

3、CLR(公共語言運作庫)在運作期管理程式的執行:主要包含:記憶體管理、代碼安全驗證、代碼執行、垃圾收集。如下圖

(1)自動垃圾收集:CLR有一項服務稱為GC(Garbage Collector,垃圾收集),它能為你自動管理記憶體。

       1)GC自動從記憶體中删除程式不再通路的對象

       2)GC是程式員不再操心許多以前必須執行的任務,比如釋放記憶體和檢查記憶體洩漏。這可不是小特性,因為檢查記憶體洩漏可能非常困難而且耗時。

4、代碼的編譯過程:

(1)編譯成CIL:.NET語言的編譯器接受源代碼檔案,并生成名為程式集的輸出檔案。程式集可以是可執行檔案或DLL(如下圖所示)

1>程式集裡的代碼并不是本機代碼,而是一種名稱為CIL(Common Intermediate

Language,公共中間語言)的中間代碼。

       2>程式集包含的資訊中,包含下列項目:程式的CIL、程式中使用的類型的中繼資料、對其他程式集引用的中繼資料

   (2)編譯成本機代碼并執行:程式的CIL直到它被調用運作時才會被編譯成本機代碼。在運作時,CLR執行下面的步驟(如下圖)

        1>檢查程式集的安全特性

        2>在記憶體中配置設定空間

3>把程式集中的可執行代碼發送給實時(Just-in-Time)編譯器,把其中的一部分編譯成本機代碼。  

程式集中的可執行代碼在需要的時候由實時編譯器編譯,然後它就被緩存以備在後來的程式中執行,使用這個方法意味着不被調用的代碼不會被編譯成本機代碼,而且被調用到的代碼隻被編譯一次。

一旦CIL被編譯成本機代碼,CLR就在它運作時管理它,執行像釋放無主記憶體、檢查數組邊界、檢查參數類型和管理異常之類的任務。這裡産生了兩個重要的術語:

       托管代碼:為.NET架構編寫的代碼稱為托管代碼,需要CLR。

       非托管代碼:不在CLR控制之下運作的代碼,比如Win32C/C++

DLL,成為非托管代碼。

  (3)編譯和執行綜述:無論原始源檔案的語言是什麼,懂遵循同樣的編譯和執行過程。