背景

在 .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.ObjectSystem.StringSystem.Threading.ThreadSystem.Threading.Tasks.Task 和大多数基本接口)包含在 CoreCLR 源代码中,并通过 System.Private.CoreLib.dll 提供给 CoreFX。

CoreFX 中虽然也有 System.Object 的声明,并最终生成 System.Runtime.dll,但其定义属于一种外观(facade),当我们使用到 System.Object 时,引用会被转发到 System.Private.CoreLib.dll 中。

也就是说,如果我们想要查看一些基本类(例如 System.StringSystem.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 源代码相关推荐

  1. eclipser认java源码_java相关:Eclipse查看开发包jar里源代码的方法

    java相关:Eclipse查看开发包jar里源代码的方法 发布于 2020-5-21| 复制链接 摘记: Eclipse查看开发包jar里源代码的方法前言:最近我打算学习一下谷歌的类库Guava,下 ...

  2. Debug ASP.NET Core 2.0源代码

    首先你的VS必须为VS 2017 15.3或以上版本. 打开你的Startup类,在ConfigureServices方法上设置个断点,按F5 Debug应用. 在Call Stack(调用堆栈)窗口 ...

  3. 如何查看.net core 最新版本的功能

    .net core 最新版本功能 查看 .net core 新特性 :如下图 访问地址 就能进入并看到上面的界面了 https://docs.microsoft.com/zh-cn/dotnet/co ...

  4. 手机chrome查看源代码_如何查看Chrome扩展程序的源代码

    手机chrome查看源代码 Every Chrome extension that you install on your computer is actually constructed out o ...

  5. 如何查看OpenCV自带函数的源代码

    OpenCV提供的内部函数能实现好多图像处理功能,有时我们需要改进函数或者想看一下函数的具体实现,一般有以下两种方法来查看其内部函数代码: 方法一:在opencv的安装文件夹中找到 与头文件名字对应的 ...

  6. Rk3288运行linux,查看“Firefly-rk3288 build linux”的源代码

    因为以下原因,您没有权限编辑本页: 您所请求的操作仅限于该用户组的用户使用:用户 该页面已被保护以防止编辑和其他操作. 您可以查看与复制此页面的源代码.=编译firefly linux-SDK系统= ...

  7. 调试 ASP.NET Core 2.0 源代码

    在Visual Studio 2017中可以通过符号以及源链接,非常方便对 ASP.NET Core 2.0中源代码进行调试.在这篇文章中,我们将重点介绍如何使用源链接对ASP.NET Core源进行 ...

  8. php捉迷藏,查看“蘑菇捉迷藏!”的源代码

    因为以下原因,您没有权限编辑本页: 您所请求的操作仅限于该用户组的用户使用:用户 您可以查看与复制此页面的源代码.'''蘑菇捉迷藏!'''(きのこの 隠れんぼ!)是[[精灵宝可梦 黑2·白2]]中的[ ...

  9. php禁止查看源代码,查看“禁止视频网站”的源代码

    因为以下原因,你没有权限编辑本页: 您所请求的操作仅限于该用户组的用户使用:用户 您可以查看并复制此页面的源代码:{{DISPLAYTITLE:如何禁止视屏视屏网站?}} 本文将介绍如何使用WFilt ...

最新文章

  1. MapReduce编程系列 — 2:计算平均分
  2. bs程序在linux下部署,在windows10 Linux (centos7)中安装go golang (够浪) 并测试运行
  3. PostgreSQL — 基于 Recovery 流复制的数据备份
  4. 文字居中 qt_Qt编写自定义控件11-设备防区按钮控件
  5. Anaconda+vscode+pytorch环境搭建
  6. Linux函数--inet_pton / inet_ntop
  7. mysql8.0.4以后_mysql官方源从8.0.3直接通过yum源升级到8.0.4后启动不成功解决方法...
  8. 【bzoj3669】[Noi2014]魔法森林【LCT】
  9. JavaScript基础和Web APIs两个阶段的关联性(1)
  10. linux ssh 虚拟机下CentOS7开启SSH连接
  11. 数学建模——主成分分析及spss软件操作
  12. Web渗透测试实战——(2.1)Metasploit 6.0初步
  13. QNAP 威联通 NAS的个人使用经验 篇三:#剁主计划-西安# 时隔3年,NAS使用须知
  14. Oracle MySQL sql 列转行 union all 实现
  15. 基于JSP小型超市管理系统
  16. 强化物联网连接 Silicon Labs收购Micrium
  17. Aras innovator: 如何制作一个itemtype的BOM结构
  18. (山理工 1243)母牛问题(大牛生小牛,小牛生。。。。)
  19. 【Excel】用excel生成矩阵
  20. Marked.js - HTML 中直接解析显示 Markdown

热门文章

  1. Objective-C征途:Hello Objective-C
  2. axure文本框值相加_Axure教程:计数文本域实现
  3. C#将unix时间戳转换成.net的DateTime类型的代码
  4. 《Python编程快速上手 让繁琐工作自动化》pdf
  5. IIS应用程序池相关问题及连接池已满的解决方法
  6. 02 JRE与JDK
  7. LeetCode: 14. Longest Common Prefix
  8. 使用Azure Pipelines来实现Teams App的CI
  9. 百度新闻 谷歌新闻_每日新闻摘要:到目前为止,Google I / O提供的最佳信息
  10. windows运行对话框_如何在Windows运行对话框中添加文本快捷方式?