很多人沒有將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)編譯和執行綜述:無論原始源文件的語言是什么,懂遵循同樣的編譯和執行過程。

轉載自 https://blog.csdn.net/lidandan2016/article/details/77868043
