學術交流,我們組準備的是《.NET與VB.NET》,我負責的是.NET Framework基礎與VB.NET編譯原理這兩個主題,但是我寫著就發現,如果瞭解.NET Framework,VB.NET編譯原理實際上包括在這裡面的,所以寫著寫著就變成了一個主題,本文就從宏觀上來給大家介紹一下.NET。
思維導圖
為了從宏觀角度看,我畫了一個思維導圖。
具體來說,我要說的幾個方面是:
什麼是架構
解釋.NET之前,得先來說一下什麼是Framework,翻譯過來就是“架構、架構、結構、體系”,總而言之它指的是一類事物、問題的宏觀指導和解決方案。所以我們可以把.NET Framework理解為.NET這一整套體系的指導和解決方案,這算是一個概念,執行個體化之,就是你安裝的.NET
Framework x.x。
.NET目的
我們在學一個知識之前要知道它從何而來,要做何用,我的理解是.NET 推出的原因主要有這幾點:
以下會著重來說前兩點。
.NET組成 按照先宏觀再細節,逐層細化的原則,我們首先需要看看.NET組成。 .NET組成圖 如果一上來就按下面左邊這張圖說,老師該揍我了,所以畫了下面右邊這張圖,這樣從上而下逐層看會更容易理解。
FCL
因為本文只是宏觀的介紹,所以它所代表的英文縮寫大家百度即可。
FCL在.NET中表現為各種各樣的類,例如寫一個語句:
SqlConnection con = new SqlConnection(conn);
實際上使用的就是FCL中的SqlConnection類,因為都是一些“靜止”概念的類,我們可以把它理解為.NET的"屬性",根據它們之間自上而下的依賴,分為三層:
- 基礎類庫,由BCL大部分組成,說白了就是.NET中一些基礎類。
- 功能類庫,XML類庫、GDI+等,它包含的是對作業系統功能的封裝的類,如I/O操作等的類。
- 應用程式層,WinForm、Asp.NET,每個程式設計語言特有的類。
BCL
如上面所說,它是.NET類庫的基礎部分,大部分包含在FCL中的系統類別庫中,是最基礎的類庫,我們以建立一個C#項目為例,建立後開啟物件瀏覽器,看到的mscorlib,就是BCL的一員,它在引用中是無法刪除的。
CLR 它是.NET的執行引擎,負責的是對FCL中類的操作和使用,我們可以把看做.NET的"函數、事件"(即動態),它主要有兩個方面的作用。
- 和JAVA的JVM一樣,它保證應用和底層作業系統之間解耦合
- 負責.NET程式的自動管理,比如資源管理、安全檢查、異常管理等。
看一下CLR的常見功能圖:
CTS和CLS
CTS是一套規則、一個協議,是對語言宏觀的規範,定義了語言可以做什麼,不可以做什麼,具有哪些特性。
任何符合這套規則的進階語言就可以稱為面向.NET架構的語言(不必全部符合),這意味著.NET拓展性非常好,可以添加其它進階語言。
CLS是CTS的一個子集,它也是一套規則協議,不過和CTS不同的是,它是對語言細節的規範:以.NET平台為目標的語言必須支援的最小特徵,例如是否區分大小寫、命名規則、標識符、建構函式如何使用……
從上面的組成圖可以看到,CTS和CLS位於程式設計語言和CL之間,這兩者的作用就是規範和介面,使不同的程式設計語言都可以和FCL相通,當然,這就減少了不同語言之間引發的互通性問題。
MSIL
微軟中繼語言,它類似於組合語言:比機器語言進階,但又不是進階語言。它是代碼編譯後的中繼語言,它沒有與CPU或作業系統掛鈎的內容,所以是與CPU解耦的,之所以說它是中繼語言,是因為.NET下所有的語言編譯後都是MSIL。
因為它是一種中繼語言,CPU不能直接執行,所以MSIL經過即時編譯器的解釋,才形成了可執行檔機器代碼,雖然比以前類似VB的語言多了一步,但是這為跨平台執行提供了可能。
中繼資料與清單
它是編譯後的一組表格,這個表格包含了所編譯內容的基本資料,例如:規定在程式中編譯哪些類、 類的成員資訊、依賴於哪些程式集……。它相當於一個清單、目錄,將一些宏觀的內容提取出來,方便程式查閱。
之所以囉嗦講這麼多的概念,是為後面跨平台、跨語言的解釋做準備。
跨語言
.NET下很優秀的一個功能就是跨語言,何為跨語言?就是.NET上不同語言可以相互使用,甚至繼承,為此寫了一個簡單的Demo:大意是使用VB.NET寫一個類並編譯成dll,在C#中引用,並繼承使用。
VBNETClass.vb
VB.NET語言編寫的一個類,很簡單,只是返回一個字串,表明這是一個VB.NET的類。
Public Class VBNETClass Public Function GetClassType() As String Return "My type is VB.NET" End Function End Class
打成dll並引用到C#項目中:
加紅顯示的VBNET即是我們編譯上面VBNETClass類形成的dll,加紅顯示的其它內容表明這是一個C#程式。
CSharp.cs
添加對VBNET的引用,建立了一個名為CSharp的C#類,使用其繼承VBNETClass。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using VBNET;namespace WindowsFormsApplication1{ public class CSharp :VBNETClass { }}
因為繼承,類CSharp中已包含VBNETClass的GetClassType()函數。
執行
寫成一個視窗程序,執行。
private void button1_Click(object sender, EventArgs e) { CSharp csharp = new CSharp(); MessageBox.Show(csharp.GetClassType().ToString()); } 運行結果
為什麼用兩種不同語言編寫的可以相互引用?下面即將揭曉……
跨平台
所謂的跨平台,是指可以跨越作業系統或硬體,例如windows系統下編的考試系統可以啟動並執行Linux下,下面這張圖顯示的是常見的作業系統和CPU。
二者原理
跨語言和跨平台的原理是什嗎?
跨語言 還記得上面提到的MSIL、CLS和CTS、中繼資料和清單否?正是因為這幾部分的配合,才實現跨語言,以上面咱們的跨語言例子為例,流程如下:
- VB.NET和C#都符合CTS,從而保證二者有一致的行為基礎
- CLS的存在,使得二者有資料類型的通訊基礎,映射關係如下:
- 二者相互連信
跨平台
例如要在Linux下運行Windows下編譯的程式,首先需要做的是在Linux上面安裝該系統下的.NET運行環境Mono。還是因為MSIL的存在,及與CLR的配合,將其解釋成本地可執行檔代碼,過程如下:
- 複製編譯的DLL到linux系統,配置Mono運行時
- 使用Mono的解譯器將複製來的DLL解釋為Linux可識別的代碼
- 運行程式
當然,上面說的是理想的情況,就實際情況而言,其它系統的.NET運行環境要麼不存在、要麼功能有限,另外Windows下的.NET封裝了Windows的API,這些功能在其它系統上如何?也是很頭疼的一件事。
執行流程
為了更好的理解跨平台和跨語言,我們來看一下從代碼到執行的過程。
流程如下:
- 將.NET 原始碼編譯成MSIL
- CLR即時編譯器將MSIL解釋為本地代碼
- 執行代碼
從圖上宏觀看,CLS部分解釋了跨語言,CLR部分解釋了跨平台。
知識拓展 反編譯
使用.NET Reflector可以將DLL反編譯為原始碼,將EXE或DLL反編譯所得,可能和真正代碼有出入,但是對我們來說,知道思路已經足夠,如下:
防編譯
目前而言,還沒有切實的方法防止反編譯,可以將類名和類的成員名稱修改為無意義字串,反編譯仍可以理解,但是花費的時間會大幅增加。
反射原理
以下是在驗收張薄的收費系統時看到的一段反射代碼:
它的大致原理是:
- 根據DLL的名稱載入該DLL
- 根據類名、中繼資料和表單(見上),載入類
如果只需要載入類,此處已經完成,但是咱們需要將其轉化為符合指定介面的類,所以添加了強制類型轉換語句。
這個大家有興趣可以深究一下,這裡只是為大家提供一個宏觀的思路。
總結
.NET基礎就先說到這裡,基本上從宏觀上解釋了一下.NET,如有錯誤,歡迎指正。
建議將PPT和本文配合閱讀,PPT:《.NET
Framework》。