16-03-C#数据结构源码-附录C-参考资源

附录 C:参考资源

系列 :C# 与常用数据结构源码剖析 · 附录

统计口径 :截至 2026-08-14,00---16 共 17 个内容目录、90 个内容 Markdown 文件;另有根级 Plan.md、文生关键词、质量审核记录以及验证说明/结果共 5 份支撑材料,故物理总数为 95。90 篇内容包含导览、篇章概要和附录,不表示 90 篇独立技术正文。

链接访问日期 :2026-08-14。网站和 main 分支会变化;本专栏的 .NET 8 源码基线固定为 dotnet/runtime@5535e31a712343a63f5d7d796cd874e563e5ac14,.NET 9 泛型 OrderedDictionary 基线固定为 dotnet/runtime@9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3。其他实现引用也应使用 commit permalink 并记录访问日期。

一、规范与官方 API 契约

规范回答语言/平台必须保证什么,API 文档/reference assembly 回答某 TFM 能调用什么。它们不代替私有实现源码或性能测量。

二、官方源码与设计资料

从 GitHub 网页复制源码链接时,优先使用包含 commit SHA 和行号的 permalink。不要用 blob/main/... 链接证明已发布 .NET 8 的字段或算法。参见 附录 B:源码索引速查。

三、Unity 官方资源

Unity 证据必须记录 Editor 完整版本、API Compatibility Level、包版本、Mono/IL2CPP、构建配置、目标设备和 Profiler capture。桌面 CoreCLR 源码或 Editor 运行结果不能替代目标 Player 证据。

四、实验、IL 与性能工具

工具结果必须与它的版本和配置一起解读。微基准回答特定局部问题,堆快照回答采集时刻的对象图,事件跟踪回答某段时间的行为;任何一种都不应被单独提升为无条件结论。

五、书籍与系统化阅读

  • Jeffrey Richter, CLR via C#, 4th Edition --- .NET Framework 时代 CLR/C# 心智模型。具体私有实现需与现代 .NET 源码重新校验。
  • Konrad Kokosa, Pro .NET Memory Management, 2nd Edition --- GC、分配、内存诊断与性能方法。
  • Jon Skeet, C# in Depth, 4th Edition --- C# 语言特性、语义和演进。后续语言特性需补充官方规范/提案。
  • Ben Watson, Writing High-Performance .NET Code, 2nd Edition --- .NET 性能设计与测量思路;版本性数字需重新实测。
  • Maurice Herlihy and Nir Shavit, The Art of Multiprocessor Programming, 2nd Edition --- 线性化、无锁算法与并发正确性。
  • Thomas H. Cormen et al., Introduction to Algorithms --- 复杂度、哈希、树、堆和均摊分析。

书籍建立长期模型,但无法代替当前 API 文档和发行 tag。引用某个固定数字、字段或平台差异时,需标明版次/页码,并在当前目标环境复核。

六、引用记录模板

复制代码
主题:Dictionary<TKey,TValue>.TryInsert
契约:.NET API Browser / net8.0 reference assembly
源码:dotnet/runtime,tag v8.0.0,commit 5535e31a712343a63f5d7d796cd874e563e5ac14
路径:src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs
永久链接:https://github.com/dotnet/runtime/blob/5535e31a712343a63f5d7d796cd874e563e5ac14/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs
测试:同 tag 下对应单元测试路径
访问日期:2026-08-14
实验:SDK/runtime/OS/CPU/GC/输入分布/原始报告

这个模板强制分开契约、私有实现、测试和性能证据。一个 GitHub PR 能说明改动动机和 diff,却不自动证明已发布到某 SDK,也不自动证明在 Unity/IL2CPP 上有相同行为。

七、证据层级:先确定资料能回答什么

技术资料没有一个能够通吃所有问题的"最高权威"。规范对语义契约很强,却不说某版本 CoreCLR 的私有字段;源码能告诉我们某个 commit 如何实现,却不能单独证明另一个运行时或平台的实际性能。使用资料前要先把待证明的命题分类。

证据层 适合回答 不能单独回答
语言、CLI 与内存模型规范 程序必须遵守的语义、转换、可见性和元数据规则 私有布局、当前 JIT 代码形状、具体耗时
reference assembly 与 API 文档 某 TFM 是否有类型、成员、重载、异常与公开契约 私有算法、实际内联、Unity 目标 Player 是否兼容
固定 commit 的实现源码 字段、辅助方法、算法分支和实现不变式 公开承诺、另一 tag 的行为、目标机器性能
同 tag 的单元测试 实现者重点保护的边界、异常、回归和平台差异 所有未覆盖行为、业务语义或性能上限
设计文档、issue 与 PR 动机、替代方案、审查争议和改动时间线 最终发布状态、当前代码与客户端可观测结果
生成的 IL、机器码与跟踪 某个编译器、运行时、架构和输入下实际发生了什么 其他配置的普遍结论、长期稳定的 API 契约
可重复基准与业务回放 特定负载下的延迟、吞吐、分配、峰值与成本曲线 没有测量的输入分布、另一 CPU 或未来版本
技术书籍与二手文章 心智模型、历史背景、研究入口和关键词 需要精确 tag、API 或平台的最终证明

证据冲突时,不用"新资料一定胜旧资料"或"官方博客一定胜实验"粗暴裁决。先检查它们是否在回答同一问题:规范可能在说公开语义,源码在说某 commit 的实现,基准则在说某台机器的特定负载。如果确实冲突,记录版本、原始引文和实验条件,把冲突本身作为待验证问题,而不是悄悄删除不合预期的证据。

八、资料评估:七个问题比"是否官方"更有用

收录一份资料前,可用七个问题评估它。第一,主张是什么 :是 API 存在性、算法形状、性能数字,还是设计动机?第二,适用对象是什么 :语言、TFM、运行时、SDK、Unity Editor、包还是目标平台?第三,版本是否可定位:有没有 tag、commit、版次、发布日期或完整 Editor patch?

第四,证据是否直接 :资料是展示了代码、报告和原始数据,还是只引用另一篇摘要?第五,能否复现 :是否给出输入、环境、构建配置、预热、重复次数和结果校验?第六,边界是否明示 :作者是否把内部实现当成公开契约,把相关性当因果,或把一次快照当长期趋势?第七,能否被反驳:是否存在一种可观测结果会迫使主张修改?

高风险信号包括:不写版本却逐字展示私有字段;声称某容器"始终 O(1)"却不区分均摊、期望和最坏;只报一个快多少倍而没有功能校验;用 Editor 结果代表 IL2CPP 真机;用 main 分支解释已发布 tag;将 issue 中的设想当成已合并 API;只给截图而没有命令、报告和构建标识。这些信号不意味资料必然错,但意味着它只能做线索,不能直接成为教材结论。

可将评估结果写成一张"证据卡":一句原子主张、证据层、适用版本、原始链接或文献位置、能复现的最小步骤、已知反例、当前信心等级与待办验证。将"看过一篇文章"变成结构化记录,才能在半年后回答当时为什么相信它。

九、引用方法:一个引用只承载它真正支持的结论

可审查的引用从"原子主张"开始。不要用一个源码链接同时支撑"API 存在、这是公开承诺、它比另一方案快三倍"三件事。前两件事至少需要 reference assembly/API 契约与实现源码分别证明;性能主张还需要可重复实验。

契约类句子应写明目标版本,例如"在 net8.0 reference assembly 中,该成员的公开签名为......"。实现类句子应写"在 dotnet/runtime 的给定 commit 中可观察到......",避免把私有形状写成所有 .NET 的永久真理。性能类句子则需说"在以下环境与输入中观察到......",同时链接原始报告,不将结果扩展到未测平台。

引用源码时保存仓库、commit SHA、路径、类型/方法名与行号。行号是导航信息,commit 才是内容身份;后续文件增删行不应让旧引用漂到新逻辑。引用一段算法时只摘录论证所需的最小范围,并标注"逐字源码"、"结构化节选"还是"教学伪代码"。后两者不应伪装成仓库原文。

引用设计提案或 PR 时同时记录状态:草案、合并、回退、发布或仅在 preview。"PR 已合并"不等于"项目目标 TFM 已提供";合并后还要确认所在分支、首个发布 tag 与 reference assembly。引用书籍则记录版次、章节/页码和它面向的产品世代,不用现代 .NET 名词悄悄改写旧 CLR 的实现结论。

跨文章重用同一结论时,应引用同一张证据卡或固定来源,而不是将转述层层当成新证据。一处基线更新后,通过搜索 commit、API 名或证据卡 ID 定位所有消费者,能减少"总文已修正,面试篇仍保留旧说法"的内部矛盾。

十、Unity 版本固定:不用"Unity 6"代替实验坐标

Unity 的证据坐标比普通 net8.0 项目更长。至少记录 ProjectVersion.txt 中的完整 Editor 版本与修订标识、Build Target、OS/CPU 架构、Scripting Backend、API Compatibility Level、Managed Stripping Level、Development Build、Incremental GC、脚本定义符号、重要 Player Settings 与构建 commit。只写"Unity 2022"或"Unity 6"无法区分编译器、类库、IL2CPP、裁剪器和平台工具链的变化。

包版本不能只从文章的访问日期猜测。保存 Packages/manifest.json 与 lock 文件,记录 Burst、Collections、Entities、Memory Profiler、异步库、热更框架与源码生成器的确切版本。官方包文档的 latest 链接只用作发现入口;项目结论应换成对应已安装版本的文档页,并保存 manifest/lock 作为可审计事实。

编译证据、Editor 行为和 Player 行为要分开。一个最小探针应同时保留:编译器能否识别语法;reference assembly 是否有需要的类型和重载;Mono Editor/Player 是否执行通过;IL2CPP Player 在项目裁剪级别下是否保留反射成员与闭合泛型路径;真实设备上的线程、ABI、原生插件、异步续体和 Job 生命周期是否正确。语法通过不会自动证明后四层。

对性能资料,还要记录 Profiler 连接方式、Deep Profile、Safety Checks、Burst 开关、画质、帧率限制、温度和电源模式。Editor、Development Player 和 Non-Development Player 是三种不同的观测环境;Editor 适合定位,Development 适合获取详细证据,最终预算则应回到最低档目标设备与接近发布的配置。若平台不同时支持 Mono 与 IL2CPP,不能把两台不同设备的差异简化成后端差异。

十一、实验归档:让结论能在另一台机器上重建

一份可复现实验不只有结果表。最小归档包含六类产物:可从干净检出构建的源码与依赖锁定;创建输入和运行实验的脚本;完整环境清单;未经挑选的原始报告、trace、dump 或 capture;从原始数据生成表格的处理步骤;以及功能等价的 checksum、断言和回归测试。只保留一张柱状图,无法检查是否删掉了工作、改变了语义或隐藏了异常样本。

环境清单至少覆盖 OS 及补丁、CPU 型号/微码与架构、核数和频率策略、内存、SDK/runtime 完整版本、GC 模式、JIT/AOT/ReadyToRun/PGO、Release/Debug、进程位数、容器/虚拟化、工具版本和关键参数。数据结构实验再加元素类型与大小、容量、命中率、键分布、冲突率、读写比、初始容量、串并行度和随机种子。这些不是装饰元数据,而是结果的定义域。

原始产物应与解读分开。原始目录只追加、不手工修补;清洗脚本输出到新目录;文章表格记录从哪份原始数据与脚本生成。产物名可包含日期、commit 短 SHA、运行时、平台、场景和重复编号,但真实身份仍由 manifest 中的完整值确定。大文件无法进 Git 时,保存内容哈希、对象存储位置、保留期和访问权限,不要只在个人桌面留一份不可定位文件。

运行前定义排除条件,不要看完结果再删样本。例如设备进入热降频、背景更新占用 CPU、功能 checksum 错误、输入未完整消费或 Profiler 断开,都可以是事先声明的无效运行。有效运行应报样本数、分位数、离散程度和异常上下文,不用平均值掩盖双峰或慢尾。对比方案必须使用同一功能 oracle;如果一方不维持顺序、不处理失败或不包含构建成本,就要分开报告,不把不等价工作排名。

归档前要处理安全与隐私。dump、heap snapshot、trace 参数、路径、符号和测试输入可能包含凭据、玩家标识、请求内容或商业数据。脱敏应保留调查所需的结构,并记录修改过程;不得为了复现而将生产快照上传到公开仓库或第三方在线分析工具。

十二、失效链接与漂移结论的维护

链接可打开不表示证据仍有效。官方文档可能保留同一 URL 却默认切到新版本;GitHub main 可能完全改变文件;包文档的 latest 会指向新主版本;搜索结果的摘要可能来自旧缓存。因此维护同时检查"能否访问"和"现在内容是否仍支持原主张"。

将链接分为三类管理。第一类是可固定的证据,例如 commit permalink、发布 tag、规范版次和有版本的包文档,文章结论优先使用它们。第二类是浮动入口,例如 API Browser、项目主页和文档导航,用于发现新资料,不独立承载私有实现主张。第三类是外部二手资料,保留作者、标题、日期和必要摘要,并尽可能追溯它的一手来源。

可以在每次大版本升级、每次全专栏发布前和固定周期执行链接审计。自动检查负责 HTTP 状态、重定向、内部相对路径和锚点;手工检查负责版本选择、主张是否仍存在、页面是否已改为 preview 或新产品线。只有 200 OK 的检查会漏掉最危险的语义漂移。

发现失效时不默默换成"看起来相似"的新页面。先确认新来源支持同一主张和版本,再更新访问日期与证据卡。如果无法找到等价来源,将结论降级为待验证、删除过度精确的说法,或保留注释说明原证据已不可达。维护历史不是为了永久保留旧 URL,而是防止结论在换链接时悄悄改变。

十三、典型研究路线

13.1 查一个 API 在项目中是否可用

先写清项目的 TFM 或 Unity API Compatibility Level,再查 reference assembly 和官方 API 文档的版本选择。然后用最小项目直接编译准备使用的精确签名,不用 IDE 补全或另一台机器的 SDK 作证。若涉及 Unity,继续构建并启动目标 Player,尤其覆盖裁剪、AOT 泛型、反射和原生互操路径。最终结论是"在这个坐标中可用",不是"C# 支持"。

13.2 解释一个集合的私有实现

从公开契约列出不能被实现改动破坏的行为,再锁定运行时 tag 和 commit。按公开入口追踪到私有字段与核心方法,同时阅读同 tag 测试,用空集合、边界容量、重复、冲突、异常和枚举修改构建不变式。文章中将逐字源码、结构化节选和伪代码分别标记,并列出 Unity/旧 TFM 不能直接套用的边界。

13.3 验证一个性能主张

把"A 比 B 快"改写成包含操作、输入、语义、环境和指标的可反驳假设。先用正确性 oracle 保证两方完成同一工作,再用 profile/trace 证明该操作确实位于重要路径。微基准分离机制,业务回放验收系统影响;同时记录分配、常驻内存、峰值、慢尾和能耗等交换。结果保留曲线和原始报告,不只报最有利的一个参数点。

13.4 研究一次版本演进

先选择两个已发布端点,用 API diff 区分公开表面变化,再比较固定 commit 中的源码和测试。通过 PR/issue/设计文档追溯动机,但以发布 tag 确认交付状态。将 BCL 实现、JIT 代码生成、GC、SDK 默认值和硬件分成独立变量,不把它们全写成"新 .NET 优化了集合"。性能对比用同一源码、功能校验与尽可能对齐的发布配置,并公开无法对齐的差异。

13.5 评估一个并发结构

先写公开协议:顺序、单次操作的原子边界、完成/取消、容量和过载策略。然后在固定源码中标出线性化点、锁/CAS 范围、发布语义、重试和用户回调边界。测试分为可控交错、长时间压力与业务不变式;验证不丢、不重、顺序和完成协议,而不只比较每秒操作数。"线程安全"不自动保证多键事务、公平、无饥饿或元素对象的内部安全。

十四、发布前的资料与引用审查清单

  1. 每个可能随版本变化的主张,是否写了 TFM、runtime tag/commit、Unity patch 或包版本?
  2. 是否把语言规范、API 契约、私有实现、设计动机和性能结果分开?
  3. 公开 API 是否在目标 reference assembly 或最小项目中编译,而不是只看网页搜索结果?
  4. 源码引用是否使用完整 SHA 的 permalink,并保存仓库、路径、方法和行号?
  5. 代码是否明确标注为逐字源码、结构化节选、伪代码或业务示例?
  6. 是否查看同 tag 测试,并用反例检查文章概括没有超出源码和公开契约?
  7. PR、issue 或 proposal 是否记录了状态和首个发布版本,没有把提议写成已交付事实?
  8. 书籍是否写了版次和页码,其产品世代是否与当前结论区分?
  9. 性能数字是否有源码、输入、环境、功能 oracle、样本量、原始报告与失效条件?
  10. 对比方案是否完成同一工作,包括顺序、异常、分配、构建和清理边界?
  11. 是否报告分位数、波动和异常样本,而不是只发布平均值或最佳一次?
  12. Unity 结论是否记录 Editor、包、API profile、后端、裁剪、平台、设备和构建配置?
  13. Unity 动态路径是否真正启动 IL2CPP Player 执行,而不是只生成了构建产物?
  14. Profiler、Deep Profile、Development、Safety Checks 和设备热降频等观察者效应是否在结论中公开?
  15. 实验原始产物是否可定位、可验证哈希、有保留期,且与人工整理的图表分开?
  16. dump、快照、trace、路径和输入是否完成隐私、凭据与访问权限审查?
  17. 所有相对链接、锚点和外部链接是否可达,浮动页面内容是否仍支持原主张?
  18. 失效链接的替代来源是否与原版本和主张等价,还是无意中改写了结论?
  19. 同一主张在导览、正文、面试篇和附录中是否共用同一版本边界,没有内部矛盾?
  20. 如果证据不足,文章是否明确降级为"待验证"或"仅限当前实验",而不是用自信语气填补证据空缺?

这份清单的目标不是让每一句话都堆满脚注,而是让影响正确性、兼容性和性能决策的关键主张可追溯。基础定义可集中引用规范和术语表;源码结论、版本时间线、Unity 兼容性与性能数字则应在最接近主张的地方给出可复核证据。当读者能从一个结论追到版本、代码、测试与原始报告,参考资源才不是文末装饰,而是教材级技术文章的可验证基础设施。

上一篇 :附录 B:源码索引速查

返回 :附录概要

相关推荐
天神哥哥啊2 小时前
unity联调注意事项-安卓
android·unity·游戏引擎
天神哥哥啊2 小时前
unity联调注意事项-IOS
unity·ios·游戏引擎
asdzx672 小时前
Excel 水印方案对比:页眉图片 vs 背景图片(附 C# 实现)
c#·excel
影寂ldy2 小时前
C# TCP转串口Modbus网关终极完整版笔记(队列防抖+一问一答+帧解析+双客户端轮询)
笔记·tcp/ip·c#
可爱系程序猿13 小时前
Unity 材质预览才弹 d3dcompiler_47.dll?先分清编辑器 SDK、着色器缓存和玩家包
程序人生·3d·unity·电脑·材质
xcLeigh14 小时前
Unity基础:使用Transform控制物体缩放——localScale与lossyScale的区别
unity·游戏引擎·教程
Chen—LSN16 小时前
C语言——文件操作(2)
c语言·开发语言·c++·经验分享·笔记·算法·c#
郝学胜-神的一滴17 小时前
游戏引擎原理与实践 01:聊聊游戏引擎的前世今生
开发语言·c++·游戏引擎·产品运营·软件工程·产品经理·untiy
淡海水19 小时前
00-Unity和C#的GC剖析与对比-全篇导览
unity·c#·游戏引擎·gc