【CLR VIA C#】 筆記一

來源:互聯網
上載者:User

標籤:

 

工作幾年了才看,記錄下筆記備忘。

 

1.CLR的執行模型
  1. 通用語言執行平台(Common Language Runtime,CLR)

  2. 原始碼-->編譯器檢查文法和分析原始碼-->託管模組(manged module)(含IL代碼)-->運行時有JIT編譯器產生cpu指令執行

  3. 託管模組由PE32|PE32+(64位)、CLR頭、中繼資料、IL代碼(中繼語言運行時轉換成CPU指令) 組成

  4. COM組件是一種規範,實現規範的DLL也可稱為COM組件

  5. 託管模組中的中繼資料描述了模組中定義了什麼以及引用了什麼。

  6. 程式集:由託管模組、資源檔被編譯器產生,包含一個mainfest清單的“組件”,可以是執行程式或DLL。

  7. 指定32位或anycpu時均可在64(64位系統中32位程式則在WOW64下執行)位下運行,可以在Environment的Is64BitOperatingSystem判斷是否為64位作業系統

  8. IL是與CPU無關的機器語言,可視為物件導向的機器語言

  9. 有JITter(JIT編譯器)(just in time)將IL即時編譯成cpu指令(不同cpu產生對應指令),只有方法第一次執行時JIT編譯器才會編譯

  10. vs中產生-->進階-->調試資訊 選擇 full則可在vs中執行即時調試功能,選擇none則不產生pdb檔案,選擇only則不共用產生代碼,pdb位源碼與IL的映射

  11. NGen.exe可以將IL代碼提前編譯成機器碼儲存到磁碟檔案中,避免運行時進行編譯,但是沒有做jit編譯器所做的高度最佳化

  12. 將IL編譯成CPU指令時,CLR執行驗證(verification)過程,以檢驗程式的健壯性和安全性。

  13. 可以用unsafe關鍵字標記不安全的代碼,CLR驗證過程會跳過不安全的程式碼。

  14. NGen.exe可提高程式啟動速度,減少應用程式的工作集,缺點是沒有防反編譯、可能失去同步、代碼未根據cpu最佳化

  15. Framework類庫(Framework Class Library,FCL)

  16. WCF :Windows Communication Foundation

  17. 一般型別系統:Common Type System,CTS

  18. c#類只能單整合,介面可以多繼承

  19. ==在引用情況下比較的是引用地址,equals一直比較值

  20. Common Language Specification:(Common Language Specification,CLS),實現通過com組件跨語言訪問的規範,是CLR下各個程式設計語言的子集。可標記[assembly:CLSCompliant(true)]特性進行檢查是否符合CLS。

2.產生、打包、部署和管理應用程式及類型
  1. 使用CSC.exe編譯c#代碼產生exe,可以通過 @回應檔名 來實現載入設定檔,預設全域CSC.rsp配置在.net檔案夾下面

  2. 中繼資料套件含:定義表、參考資料表、清單表

  3. 程式集特點:定義了可重用的類型、用一個版本號碼標記、可以關聯安全資訊。

  4. CLR只有在調用的方法確實引用了未載入程式集中的類型時,才會載入程式集。

  5. 程式集連結器:AL.EXE 可以實現產生包含不同編譯器產生的模組,或者在產生時不清楚程式集的打包要求的模組,可以添加資源檔

  6. 程式集版本資源資訊:在AssemblyInfo.cs中設定,可通過右鍵屬性查看

  7. 版本號碼規則:使用4個句點分割:主要版本號.次版本號碼.組建號(每天編譯遞增).修訂編號(每天編譯次數遞增)

  8. AssemblyFileVersion:給使用者看的版本號碼 AssemblyInformationaVersion:調用此程式集的產品的版本號碼 AssemblyVersion:CLR檢查的版本號碼

  9. 附屬組件:標記了語言文化的程式集,可用AL.exe產生

  10. 私人部署的程式集:在應用程式基底目錄或者子目錄部署的程式集

  11. 指定程式集尋找目錄:在設定檔中增加probing 節點甚至privatePath路徑,可以以分號分割,只能是子目錄。winfrom為exe.config webfrom為web.config

  12. 機器.NET設定檔案名稱為Machine.config在系統.net檔案夾下面可找到

3.共用組件和強命名程式集
  1. 弱命名程式集:普通程式集 強命名程式集:使用發行者的公開金鑰、私密金鑰進行簽名,進行唯一性標識

  2. 弱命名可以私人部署、不能全域部署,強命名可以私人部署、可以全域部署

  3. 程式集唯一標識:檔案名稱(無副檔名)、版本號碼、語言文化和公開金鑰(公開金鑰標記public key token)

  4. 使用SN.EXE建立公開金鑰/私密金鑰對,然後使用csc命令選擇/keyfile 及類 來編譯一個強命名程式集

  5. 全域組件快取(Global Assembly Cache,GAC):由多個應用程式訪問的程式集存放的公認目錄,一般在 系統/.net/assembly下,可以用GACUitl.exe進行程式集安裝

  6. GAC只能安裝強命名程式集,一般不推薦安裝到GAC,如果安裝則應該使用windows installer(MSI)進行安裝

  7. CSX.EXE尋找目錄:1.工作目錄 2.CSX所在目錄,含CLR的各種DLL檔案 3.使用/l編譯器指定任何目錄 4.使用LIB環境變數指定的任何目錄

  8. 安裝.net framework實際安裝兩套copy,一個安裝在GAC(存在多個copy以便針對不同CPU最佳化),一個安裝在CLR用於編譯(不含IL代碼,所以不依賴機器CPU)

  9. 強命名先使用私密金鑰對程式集部分資訊進行加密計算HASH,然後公開金鑰寫入程式集,最後再匯入到GAC時用公開金鑰解密結果與GAC計算結比較

  10. 如果從GAC之外載入強命名程式集,則CLR會在程式集載入後比較雜湊值,保證每次組件檔沒有被篡改,GAC優先根據CPU類型搜尋。

  11. 可以選擇延遲簽名,進行只放公開金鑰及預留雜湊儲存空間,程式混淆的話必須用延遲簽名才能澳證hash正確

  12. 設定檔的CODEBASE可以標記一個URL,CLR會自動下載檔案,自動對比時間戳記

  13. CLR解析類型引用:相同檔案已經早期繫結直接載入,不同檔案相同程式集,尋找FILEDEF表,載入清單,不同檔案不同程式集,載入被引用程式集的資訊清單檔

  14. 設定檔可實現根據public key token、語言、版本號碼來替換一個DLL的功能

  15. 發行者策略控制:為程式集指定設定檔,指定更新版本
                           

4.類型基礎
  1. 基類object包含MemberwiseClone(建立新執行個體)、Finalize(重寫以實現記憶體回收前的操作)

  2. new一個對象時會計算所有類型直到object類型的成員所佔的空間,然後傳遞參數後返回引用地址到對象

  3. is檢查對象是否相容於指定類型,as直接轉換對象,兩者好處位均不拋出異常,失敗返回false和null。

  4. 參考型別重名時可以使用using a=system.IO;如果命名空間也重名則可用外部別名方式區分。

  5. CLR建立一個進程,進程可能有多個線程,線程建立時會分配到1MB的棧,按順序執行,每個方法調用都會在調用棧中建立並壓入一個棧幀,調用後釋放棧幀。

  6. 堆上所有對象都包含:類型對象指標(GetType方法)和同步塊索引,當CLR確認方法所需要的所有類型對象都已建立,方法的代碼已經編譯之後,就允許線程執行機器碼了。

  7. 棧中最簡單的方法包含序幕(初始化為局部變數分配記憶體位null或0)和尾聲(記憶體回收以便返回至調用者)

  8. 調用靜態方法時CLR會定位與定義靜態方法的類型對應的類型對象,然後JIT編譯器在類型對象方法表中尋找與被呼叫者法對應的記錄項

  9. 調用非虛執行個體方法時JIT會找到與 發出調用的那個變數的類型 對應的類型對象,會向上找到基類,然後JIT尋找方法表

  10. 虛方法調用先檢查發出調用的變數,並更隨地址來到發出調用的對象,然後檢查“類型對象指標”成員,然後尋找方法表
                           

5.基元類型、參考型別和實值型別
  1. 基元類型:編譯器直接支援的資料類型,和System.Int32是屬於映射關係,如int、byte、float、double、decimal

  2. 不會發生資料丟失的情況下,c#允許隱式轉換,使用關鍵字checked和unchecked可以檢查是否溢出。

  3. 參考型別有託管堆分配,new後返回對象記憶體位址,實值型別一般線上程棧上分配(會初始化0),類是參考型別,結構或枚舉是實值型別都繼承自System.ValueType,參考型別傳指標地址,實值型別建立對象。

  4. 將實值型別轉換成參考型別就是裝箱,在託管堆中分配記憶體(浪費資源),返回引用地址。將參考型別轉換成實值型別就是拆箱(只能轉為原本實值型別)。

  5. 檢查同一性用ReferenceEquals,Equals預設實現同一性。

  6. dynamic在c#編譯器產生payload(有效載荷),在運行時根據對象實際類型判斷要執行什麼操作。使用了稱為運行綁定器得嘞。

6.類型和成員
  1. 類型預設訪問性為internal,可以指定friend 組件來實現程式集訪問限制。

  2. private、protected、internal、protected internal、public,衍生類別型重寫後的可訪問性要和重寫成員具有相同可訪問性。

  3. 靜態類只能定義靜態成員。

  4. partial關鍵字告訴c#編譯器,類、結構、介面的定義原始碼可能要分散到一個或多個源檔案中。CLR對該功能一無所知,完全有編譯器實現。

  5. 組件軟體編程(Component Software Programming,CSP)

  6. call可調用靜態方法、執行個體方法和虛方法,callvirt可調用執行個體方法和虛方法,不能調用靜態方法,會檢查對象是否為null,會遞迴尋找調用對象。

  7. 應減少虛方法的使用,1是慢2是不能內嵌3版本控制脆弱4定義基類時要提供簡單重載方法

  8. 應當對類使用sealed、internal關鍵字,對欄位使用private關鍵字,然後考慮protected或internal最後考慮virtual。

  9. new關鍵字用在方法上時,是告訴編譯器新方法和基類無任何關係,編譯器將認為是此類上定義的新方法。override則是認為重寫基類方法。
                           

7.常量和欄位
  1. 常量const是值從不變化的符號,值會在編譯時間確定並儲存為程式基中繼資料,基元類型均可定義為常量。常量值直接內嵌程式碼,不為常量分配記憶體。隱式為static。

  2. 靜態欄位實在第一次調用類是JIT編譯時間分配記憶體,執行個體欄位則是在構造類型的執行個體時分配。readonly只能在建構函式裡面賦值。

  3. readonly是運行時能賦值,常量則是一直固定的值。readonly不可改變的是引用,而非欄位引用的對象。
                           

8.方法
  1. 參考型別:構造器是將類型的執行個體初始化為良好狀態的特殊方法.ctor。建立參考型別時先為欄位分配記憶體(預設為0或null),然後初始化附加欄位類型對象指標和同步塊索引,最後調用類的執行個體構造器來設定初始狀態。

  2. 靜態類不會產生預設構造器,是抽象密封類。構造器中不能調用虛方法。每個重載的構造器都會預設產生所有欄位的值,所以通過this()調用其他構造器能減少IL代碼量。

  3. 實值型別:編譯器不會產生和調用預設構造器,除非顯式調用。欄位總是被初始化為0或null。在實值型別中this=new x();是允許賦值的,參考型別不行。new後再會將所有欄位賦值為0;

  4. new是建立執行個體,並不是調用預設構造器。

  5. 使用static可以建立類型構造器,類型構造器永遠沒有參數,總是私人的,會在類型首次訪問時執行。“.cctor”

  6. CLR規範要求操作符重載方法必須是public和static方法 如 operator+。

  7. 轉換操作符試講對象從一種類型轉換成另一種類型的方法,必須是public和static方法。格式:方法加implicit operator 類名 是隱式轉換,explicit operator 類名 是顯式轉換。

  8. c#擴充方法(第一個且只有第一個參數前有this),不支援擴充屬性、事件等,必須在非反省的靜態類中聲明,類名沒有限制,不能套在別的類,同時擴充了衍生類別。

  9. 部分類別中可以聲明分部方法,部分類別是密封的,關鍵詞partial.分部方法傳回型別始終是void,且被視為private,並且參數不能有out。

9.參數
  1. 可為方法、構造器和有參屬性指定預設值,有預設值的參數必須放在沒有預設值的參數後面,預設值必須是編譯時間能確定的常量值。default和new都可以建立實值型別執行個體。

  2. var不能用來聲明方法的參數類型和宣告類型中的欄位,var只能聲明方法內部的局部變數。

  3. 預設情況方法參數參考型別傳指標,實值型別傳執行個體副本。ref和out區別在於由哪個方法負責初始化對象。傳遞引用方式給方法的變數類型必須與方法聲明的參數類型相同。

  4. params關鍵字可實現可變數量的參數,只能為最後一個參數。 對效能有影響,可參考System.String的Concat方法設計。

  5. 聲明方法的參數類型時,應指定最弱的類型,寧願要介面也不要基類。如選IList而非List作為參數類型,方便擴充。一般最好將方法傳回型別聲明為最強型別。                       

10.屬性
  1. 欄位應設定為private,封裝了欄位訪問的方法通常稱為訪問器。在屬性中私人欄位稱為支援欄位。聲明屬性而扛get、set方法的實現,c#會自動聲明一個私人欄位,自動實作屬性。

  2. 在任何想要序列化或還原序列化的類型中,都不要用自動屬性,因為每次產生的私人欄位名稱不固定。

  3. 屬性不能作為out或ref參數,盡量減少屬性使用。

【CLR VIA C#】 筆記一

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.