程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#學習筆記一:CLR & C# 基礎,

C#學習筆記一:CLR & C# 基礎,

編輯:C#入門知識

C#學習筆記一:CLR & C# 基礎,


寫在前言   .Net Framework並不是Win 32 API 和COM上的一個抽象層。   某種程度上,它是自己的操作系統,有自己的內存管理器,自己的安全系統,自己的文件加載器,自己的錯誤處理機制,自己的應用程序隔離邊界(AppDomains),自己的線程處理模型等。 隨著多核計算機越來越普遍,線程處理,並發執行,並行結構,同步等方面的重要性日益凸顯。   CLR的執行模型   公共語言運行時 CLR Common Language Runtime 是一個運行時環境,保證應用和底層操作系統之間必要的分離,是.NET Framework的主要執行引擎。是可由面向CLR的多種編程語言使用的“運行時”。CLR的核心功能(內存管理、程序集加載、安全性、異常處理和線程同步等)由面向CLR的所有語言使用。CLR不關心開發人員使用哪一種語言來寫源代碼。也就是說挑選編程語言時,應該選擇最容易表達自己意圖的語言。理論上,可以用任何語言編寫代碼,只要編譯器是面向CLR的就可以了。   編譯器 可以視為語法檢查器和“正確代碼”的分析器。它們檢查源代碼,確定你寫的一切都有意義,然後輸出對你的意圖進行描述的代碼。不同的編程語言,有著不同的語法。不要低估這個選擇的價值,也許會節省大量的開發時間。 Microsoft已經創建好幾個面向“運行時”的語言編譯器,包括:C++/CLI、C# (C sharp)、Visual Basic、F#、Iron Python、Iron Ruby以及一個“中間語言”(Intermediate Language, IL)匯編器。   IL代碼 (托管代碼) 本地代碼編譯器是面向特定CPU架構的代碼。而每個面向CLR的編譯器生成的都是IL代碼 (中間語言代碼 。IL代碼有時稱為托管代碼,因為CLR要管理它的執行。它明顯的優勢在於它是CPU無關的。   元數據 IL代碼由面向CLR的編譯器產生,但它並不是編譯器產生的提供給運行時僅有的東西。編譯器同樣產生有關原始代碼的元數據。它提供給CLR關於代碼更多的東西,例如:各種類型的定義、各種類型成員的簽名以及其他數據。基本上,元數據是類型庫、注冊表內容和其它用於COM的信息。盡管如此,元數據還是直接和執行代碼合並在一起,並不處在 隔離的位置。 簡單地說,元數據是整個microsoft .net framework開發平台的關鍵,它實現了編程語言、類型和對象的無縫集成。   程序集 (assembly) 一個抽象的概念。首先,他是一個或多個模塊/資源文件的邏輯性分組。其次,程序集是重用、安全性以及版本控制的最小單元。取決於你對編譯器或者工具的選擇,即可以生成單文件程序集,也可以生成多文件程序集。在CLR的世界中,程序集相當於一個“組件”。利用“程序集”這個概念性的東西,可以將一組文件當成一個單獨的實體來對待。 對於一個可重用的、可保護的、可版本控制的組件,程序集把它的邏輯表示和物理表示分開。具體如何將代碼和資源劃分到不同的文件中,完全取決於個人。程序集的模塊中,還包含與引用的程序集有關的信息。這些信息使程序集能夠自描述(self-describing)。換句話說,CLR能夠判斷出為了執行程序集中代碼,程序集的直接依賴對象(immediate dependency)是什麼。   托管程序集同時包含元數據IL。IL是與CPU無關的機器語言,是Microsoft在請教了外面的幾個商業及學術性語言/編譯器的作者之後,費勁心思開發出來的。IL比大多數CPU機器語言都要高級。IL能訪問和操作對象類型,並提供了指令來創建和初始化對象,調用對象上的虛方法以及直接操作數據元素。甚至可以提供拋出和捕捉異常的指令來實現錯誤處理。可將IL視為一種面向對象的機器語言。   重要的提示: 允許在不同編程語言之間方便地切換,同時又保持緊密集成,這事CLR的一個非常出色的特性。遺憾的是,許多開發人員都忽視了這一特性。例如,C#和Visual Basic等語言能很多地執行I/O操作,APL語言能很好地執行高級工程或者金融計算。通過CLR,應用程序的I/O部分可用C#編寫,工程計算部分則換用APL編寫。CLR在這些語言之間提供了其他技術無法媲美的集成度,使“混合語言編程”成為許多開發項目的一個值得慎重考慮的選擇。   執行一個方法,首先必須把它的IL轉換成本地CPU指令,這是CLR的JIT (just-in-time或者“即時”)編譯器的職責。JITCompiler 是CLR的一個組件,稱為JITer 或者JIT編譯器。它在定義(某一個類型)程序集的元數據中查找被調用的方位的IL, 接著驗證IL代碼,並將IL代碼編譯成本地CPU指令。本地CPU指令被保存到一個動態分配的內存塊中。       一個方法只有在首次調用時才會造成一些性能損失。以後對該方法的所有調用都以本地代碼的形式全速運行,無需重新驗證IL並把它編譯成本地代碼。   JIT編譯器將本地CPU指令存儲到動態內存中,一旦應用程序終止,編譯好的代碼也會被丟棄。所以,如果將來再次運行應用程序,或者同時啟動應用程序的兩個實例(使用兩個不同的操作系統進程),JIT編譯器必須再次將IL編譯成本地指令。 對於大多數應用程序來說,因JIT編譯器造成的性能損失並不顯著。大多數應用程序都會反復調用相同的方法。在應用程序運行期間,這些方法只會對性能造成一次性的影響。另外,在方法內部花費的時間很有可能比花在調用方法上的時間多得多。     還需要特別注意的是: CLR的JIT編譯器會對代碼進行優化,這類似於非托管的C++編譯器的後端所做的工作。同樣地,可能花費較多的時間來生成優化的代碼。優化之後的代碼將獲得更加出色的性能。 非托管的飯嗎是針對一種具體的CPU平台編譯的,一旦調用,代碼直接就能執行。但是在托管環境中,代碼的編譯是分成兩個階段完成的。首先,編譯器遍歷源代碼,做盡可能多的工作來生成IL代碼,而為了真正的執行調用,這些IL代碼本身必須在運行時編譯成本地CPU指令,這需要分配更多的內存,並需要花費額外的CPU的時間。實踐確實表明,運行時發生的第二個編譯階段會影響性能,會分配動態內存。但是,Microsoft進行了大量性能優化的工作,將這些額外的開銷保持在最低限度。   IL和驗證 IL是基於棧的。由於IL沒有提供操作寄存器的指令,所以人們可以很容易的創建新的語言和編譯器,生成面向CLR的代碼。 IL指令還是“無類型”(typeless)的。例如,IL提供了一個add指令,它的作用是將壓入棧的最後兩個操作數加到一起。add指令不分32位和64位版本。 IL的亮點是它對底層CPU的抽象,但這並非它的最大優勢。IL提供的最大的優勢在於應用程序的健壯性和安全性。將IL編譯成本地CPU指令時,CLR會執行一個名為驗證(verification)的過程,這個過程會檢查高級IL代碼,確定代碼所做的一切都是安全的。如,驗證會核實調用的每個方法多有正確數量的參數,傳給每個方法的參數都具有正確的類型,每個方法的返回值都得到了正確的使用,每個方法都具有一個返回語句等等。在托管模塊的元數據中,包含了要由驗證過程使用的所有方法和類型信息。     將每個windows進程都放到一個獨立的地址空間,將獲得健壯性和穩定性,一個進程無法干擾另一個進程。通過驗證 托管代碼,確保代碼不會不正確的訪問內存,不會干擾到另一個應用程序的代碼。這樣一來,就可以放心地將多個托管應用程序放到一個Windoes虛擬地址空間中運行。 CLR提供了在 一個操作系統進程中執行多個托管應用程序的能力。每個托管的應用程序都在一個AppDomain中執行。默認情況下,每個托管的exe文件都在它自己的獨立地址空間中運行,這個地址空間只有一個AppDomain。然而,CLR的宿主進程(比如IIS或者MS SQL Server)  可決定在單個操作系統進程中運行多個AppDomain。   通用類型系統 CLR是完全圍繞類型展開的,這一點到現在為止應該很明顯了。類型為應用程序和其他類型公開了功能。通過類型,用一種編程語言寫的代碼能與另一種語言寫的代碼溝通。由於類型是CLR的根本,所以Microsoft指定了一個正式的規范,叫做“通用類型系統”(Common Type System, CTS), 描述類型定義和行為。利用了CTS指定的規則,程序集為一個類型建立了可視邊界,CLR則強制(貫徹)了這些規則。   事實上,並不需要去學習CTS規則本省,你選擇的語言會采用你熟悉的公式公開它自己的語言語法與類型規則。通過編譯來生成程序集時,它會將語言特有的語法映射到IL -- 也就是CLR的“語言”。   CLR讓我們意識到:“代碼的語言”和“代碼的行為”。不同語言可以定義系統的類型,添加相同的成員,語法有不同,但是類型的行為都是完全一致的,因為最終由CLR的CTS來定義類型的行為。     --------------------------------------------------------------------    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved