如何查看 .NET Core 3.1 源代码
背景
在 .NET 走向開源后,我們可以方便的查看 .NET 內部的實現方式,學習和尋找問題,甚至參與到 .NET 的開發中。
前段時間,同事需要查看 C# 的?Task 類 (System.Threading.Tasks)?的一些實現和內部的原理,想找 Task 類的源代碼來查看,卻遇到了一些阻礙……
本文借此機會介紹兩種方式來查看 .NET Core 3.1 的源代碼:
直接查看 .NET Core 源代碼
通過反編譯來查看實現
本文同樣適用于 .NET Core 3.1 之前的 .NET Core 版本;.NET 5 及之后的版本查看源代碼的方式有所改變,會在下文相關部分簡單提及。選擇 3.1 版本是因為當前 .NET Core 最新的 LTS 版本為 3.1,絕大多數公司都會選擇使用 LTS 的版本進行開發。所以本文并未過時,還能有用一段時間????
直接查看 .NET Core 源代碼
概念回顧
對于經歷過 .NET Framework 時期的巨佬們一定接觸過 CLR 和 FCL 這兩個概念:
CLR(Common Language Runtime,公共語言運行時 https://docs.microsoft.com/zh-cn/previous-versions/dotnet/netframework-4.0/8bs2ecf4(v=vs.100)?)負責內存管理、垃圾收集、JIT 編譯等。
FCL(.NET Framework Class Library,.NET Framework 類庫 https://docs.microsoft.com/zh-cn/previous-versions/gg145045(v=vs.110)?redirectedfrom=MSDN )是進行 .NET Framework 開發的標準類庫,提供了最基本的功能。例如?System?命名空間下的基本類和基類、System.Drawing?命名空間下提供的圖形處理功能 、System.Linq?命名空間下提供的 LINQ 擴展方法等。
進入 .NET Core 時代,大家一定見過這張圖:
可以看到 .NET Core 一列,Base Libraries 一行中出現了?CoreFX Class Library?( https://docs.microsoft.com/zh-cn/dotnet/standard/glossary#bcl ),它的左邊便是 FCL。我們可以理解 CoreFX 就是 .NET Core 的 FCL。而 .NET Core 的 CLR 則被稱為 CoreCLR( https://docs.microsoft.com/zh-cn/dotnet/standard/glossary#core-clr )。
獲取源代碼
要想獲得 .NET Core 3.1 的源代碼,我們主要關注這兩個 Github repo:
/dotnet/coreclr?( https://github.com/dotnet/coreclr )
/dotnet/corefx?(?https://github.com/dotnet/corefx )
注意,剛 clone 到本地時可能看不到源代碼,因為默認的?archive?分支只有一篇遷移 repo 的公告,需要將分支切換到想看的版本上才能查看到代碼。通過?tag?命令篩選要查看的 .NET Core Runtime 版本:
git tag -l 'v3.1.*'并通過?checkout?命令切換到對應版本的代碼上,例如我想查看?3.1.16?版本的 .NET Core Runtime 對應的實現:
git checkout v3.1.16我們要找的代碼大都位于?src?文件夾下。
理解 CoreCLR 和 CoreFX
結合前面回顧過的概念,我們應該可以明白這兩個 repo 的作用。但實際上,這里必須得提及?System.Private.CoreLib.dll?的概念,可以幫助我們理解為什么既需要 CoreCLR 又需要 CoreFX 的源代碼,它倆的區別是什么(?https://github.com/dotnet/coreclr/tree/v3.1.16#relationship-with-the-corefx-repository ):
CoreCLR 的設計理念是,盡可能少的包含類,只把 CLR 內部工作需要的類(例如?System.Object、System.String、System.Threading.Thread、System.Threading.Tasks.Task?和大多數基本接口)包含在 CoreCLR 源代碼中,并通過?System.Private.CoreLib.dll?提供給 CoreFX。
CoreFX 中雖然也有?System.Object?的聲明,并最終生成?System.Runtime.dll,但其定義屬于一種外觀(facade),當我們使用到?System.Object?時,引用會被轉發到?System.Private.CoreLib.dll?中。
也就是說,如果我們想要查看一些基本類(例如?System.String、System.Threading.Tasks.Task),就需要到 CoreCLR 的源代碼中尋找,而其它的一些類和方法的實現(例如 LINQ 里的擴展方法是如何工作的)則需要到 CoreFX 源代碼中查看。
如何區分代碼位于 CoreCLR 還是 CoreFX
使用 .NET Source Browser
可以參考 .NET Source Browser 工具。它可以在線查看當前最高版本的 .NET 源碼(僅限最高版本,目前也就是 6.0 preview)。
在左上角的搜索框里輸入要查看的類或方法名,如果你需要的內容出現在?System.Private.CoreLib?中,那就需要到 CoreCLR 中查看,否則到 CoreFX 查看。但由于查詢的是最高版本的 .NET 源碼,結果僅供參考。
使用 Visual Studio
直接上源代碼里搜索應該是更常用的方案,先自行判斷一下是不是基礎類,如果是則優先上 CoreCLR 中查找。使用 Visual Studio 的?轉到?(?https://docs.microsoft.com/zh-cn/visualstudio/ide/go-to?view=vs-2019 ) 功能可以輕松查找各種類、方法等內容。默認快捷鍵為?Ctrl + T。
由于源代碼里大量使用了partial(部分類)(?https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods ),而且不同平臺(Windows/Linux)實現可能不同,導致一個類或方法會在多個地方實現,請注意甄別,搜索時用最小單位來搜索,以免大海撈針。
.NET Core 3.1 和 .NET 5 的不同
.NET 5 將 .NET Core 相關的幾個 repo 合并成為一個名為?/dotnet/runtime?(?https://github.com/dotnet/runtime )的 repo(不止 CoreCLR 和 CoreFX 這兩個,可以參閱?Consolidating .NET GitHub repos? ( https://github.com/dotnet/announcements/issues/119 ) 了解)。
雖然合并了,但也差不多,在?/src/coreclr/src/System.Private.CoreLib?文件夾下可以找到?System.Private.CoreLib?相關的代碼;而?/src/libraries?中則是原來 CoreFX 的實現。
訪問不了 Github 怎么辦
由于眾所周知的原因,正常訪問 Github 變得困難,如果你嘗試了很多辦法后仍然無法穩定的訪問或下載代碼,最簡單的方法就是注冊一個 gitee 賬號,并使用 gitee 的導入 GitHub 倉庫功能。
請一定使用“從 URL 導入”,上述 GitHub repo 的 URL(后面加不加?.git?都沒問題)就是 gitee 導入時需要填寫的 GitHub repo url。導入后會在你的賬戶下生成對應的 repo。
或者干脆都不用注冊 gitee,直接用 gitee 提供的“Gitee 極速下載”(?https://gitee.com/organizations/mirrors/projects )服務,在里面搜索 CoreCLR 和 CoreFX。
小試牛刀
至此,我們已經獲取到 .NET Core 的源代碼,并了解了如何進行查看。下面大家可以試一試看看自己一直想查看的 .NET 內部實現吧。
通過反編譯來查看實現
隆重向大家推薦 ILSpy? ( https://github.com/icsharpcode/ILSpy ),這是一款開源免費的 .NET 反編譯工具,非常好用,是一款能陪伴你走完職業生涯的軟件。
獲取 ILSpy
可以直接在 Github 的 Release 頁面上下載它的 zip 包,解壓后可以直接使用,但沒有與 Visual Studio 集成。
這里主要介紹它在 Visual Studio 中的應用,有幾種方便的辦法將它與 Visual Studio 集成:
在 Github 的 Release 頁面下載 vsix 包
如果訪問不了 Github 可以嘗試 Visual Studio 擴展(擴展 - 管理擴展)中搜索并安裝 ILSpy
如果 Visual Studio 擴展下載依然很慢,可以直接通過?Visual Studio Marketplace 下載?( https://marketplace.visualstudio.com/items?itemName=SharpDevelopTeam.ILSpy )
安裝完成后,鼠標右鍵點擊要查看實現的代碼,會顯示出“用 ILSpy 打開代碼”的菜單:
在彈出的 ILSpy 窗口中查看反編譯出來的代碼:
需要注意的是,這種辦法適合只需要看一看的情況,而且反編譯得到的代碼和源代碼不是完全相同的(但執行的結果肯定是一致的)。
總結
之前同事遇到的問題就是,一開始只 clone 了 CoreFX,而 Task 類實際上是在 CoreCLR 的?System.Private.CoreLib?中定義的~ 在 CoreFX 自然查看不到實現代碼了。
通過本文的介紹,相信大家一定能快速的查看 .NET Core 的源代碼了:
直接獲取源代碼:適用于想要學習了解 .NET 源碼、組織方式、調試或致力于參與到 .NET 建設的情況
通過 ILSpy 反編譯:適用于臨時看看某些代碼的實現的情況
參考
Understanding .NET (2nd Edition)
.NET Core, .NET Framework, Xamarin – The “WHAT and WHEN to use it”?( https://devblogs.microsoft.com/cesardelatorre/net-core-1-0-net-framework-xamarin-the-whatand-when-to-use-it/ )
CoreCLR is now Open Source?(https://devblogs.microsoft.com/dotnet/coreclr-is-now-open-source/ )
.NET 術語表?( https://docs.microsoft.com/zh-cn/dotnet/standard/glossary )
希望這篇文章能對您有幫助
可以的話,別忘了“喜歡作者”哦
總結
以上是生活随笔為你收集整理的如何查看 .NET Core 3.1 源代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NET问答: 为什么 String.In
- 下一篇: .net core 下的HttpClie