.net 5+ 知新:【2】 .Net Framework 、.Net 、 .NET Standard的概念與區別

XSpringSun發表於2021-07-30

作為了解歷史和演進過程,我們需要將 .Net Framwork 、.Net、 .Net Stander幾個概念進行下理解。
.net 代表跨平臺框架,從.net 5開始就統一叫.net,廢棄原來的.net core 叫法。由於太多名字防止混淆,我們就不管.net core了。

.NET Framework

在未來.NET Framework或許成為過去時,目前還是有很多地方在使用的。這一套體系對於做C#的老coder應該是再熟悉不過了,新入坑的也就用不著費力去學習。

.NET Framework 是一種技術,支援生成和執行 Windows 應用及 Web 服務。
.NET Framework 包括公共語言執行時 (CLR) 和 .NET Framework 類庫。 公共語言執行時是 .NET Framework 的基礎。
可將執行時看作一個在執行時管理程式碼的代理,它提供記憶體管理、執行緒管理和遠端處理等核心服務,並且還強制實施嚴格的型別安全以及可提高安全性和可靠性的其他形式的程式碼準確性。

.Net

.net 就是由.net core 演進而來,在底層有很多效能和架構優化改造,上層應用api和用法和.NET Framework大多數相同。

.NET 是一種用於構建多種應用的免費開源開發平臺,使用 .NET 時,無論你正在構建哪種型別的應用(web,api、桌面應用...),程式碼和專案檔案看起來都一樣。 可以訪問每個應用的相同執行時、API 和語言功能。
NET 是開放原始碼,使用 MIT 和 Apache 2 許可證。 .NET 是 .NET Foundation 的專案。
Microsoft 支援在 Windows、macOS 和 Linux 上使用 .NET。 它會定期更新以保證安全和質量。
.NET 支援三種程式語言:C#、F#、Visual Basic。

.NET Standard

.NET Standard 是針對多個 .NET 實現推出的一套正式的 .NET API 規範。 推出 .NET Standard 的背後動機是要提高 .NET 生態系統中的一致性。 但是,.NET 5 採用不同的方法來建立一致性,這種新方法在很多情況下都不需要 .NET Standard。

所以.net standard 是 .Net Api 規範,不是實現。其作用是為了提高.net 一致性,只要框架支援就能使用.net standard規範去實現。
但是!.NET 5 採用不同的方法來建立一致性,也就是說.net 5 開始過度到.net 框架如果你只是用於.net 框架的話,但是支援.net standard!(名字有點繞暈啊)
NET Standard並未棄用 對於可由多個 .NET 實現使用的庫,仍需要 .NET Standard。比如在 .NET Framework 和 .NET 上都要使用的內庫就需要按照.net standard規範,這樣兩個框架都能用,但是要看.net standard版本支援,下圖對照。
在建立類庫的時候就可以選擇不同的支援框架。

各種 .NET 實現以特定版本的 .NET Standard 為目標。 每個 .NET 實現版本都會公佈它所支援的最高 .NET Standard 版本,這種宣告意味著它也支援以前的版本。

例子說明

1、建立一個.NET Standard 類庫,新增一個簡單的測試方法。

public class NetStandardTest
{
    public static void PrintLocation()
    {
        //列印FileStream 路徑
        Console.WriteLine(typeof(FileStream).Assembly.Location);
        //列印NetStandardTest 路徑
        Console.WriteLine(typeof(NetStandardTest).Assembly.Location);
    }
}

在這個測試方法裡面我們加了兩行列印程式碼。主要是列印FileStream路徑,同時我們建立的.NET Standard類庫為2.0,因為我們接下來要建立.net framework 的控制檯,它不支援2.1。

2、建立.net 5,.net framework 4.6.1 控制檯程式

建立好兩個控制檯專案,在主方法裡面呼叫內庫方法。

static void Main(string[] args)
{
    NetStandardTest.PrintLocation();

    Console.ReadKey();
}

解決方案結構如下

3、執行分析

從結果看我們看到同一個.NET Standard類庫,引用在不同的框架上,呼叫同一個FileStream的地址是不一樣的。
然後我們在.NET Standard類庫裡面F12定位到FileStream看到程式集如下

三個地址我們並列對比下:

C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.8\System.Private.CoreLib.dll
C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll
C:\Users\Administrator\.nuget\packages\netstandard.library\2.0.3\build\netstandard2.0\ref\netstandard.dll

我們將三個dll 用dnspy反編譯下,找到FileStream,隨便找一個BeginRead方法看下程式碼。

  • .net standard

  • .net framework

  • .net 5

從上面三個結果對比可以看到.net standard裡面是沒有實現的,只是定義了方法,也就是說定義了一種標準,說明我的類裡面有哪些東西。
呼叫的時候再根據我們當前使用的框架去找到對應框架的實現。這就是為什麼.net standard能對多框架引用,也是為什麼2.1不能被.net framework使用,因為它沒有去實現2.1新增的api。
至於為什麼我們呼叫.net standard的dll會被轉到對應框架的dll呢,這是利用Type Forwarding方式實現跨程式集型別轉移的技術成為“墊片(Shim)”,這是實現程式集跨平臺複用的重要手段。
關於這個墊片技術可以看下這篇文章https://www.cnblogs.com/artech/p/how-to-cross-platform-03.html

自此我們已經基本搞清楚了幾個概念和體驗它們是如何演進而來,以後也許用不太多.net standard了,等不斷升級以後直接就用.net 類庫就行,也不用去理解這麼多概念和技術,可以理解這些是過渡迭代的產物。

相關文章