三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

C#与常用数据结构源码剖析-全篇导览

C#与常用数据结构源码剖析-全篇导览

C#与常用数据结构源码剖析 — 全篇导览

系列总览:90 篇文章 · 16 篇章 · 16 主题文件夹
定位:从 C# 底层运行时到 BCL 100% 数据结构源码全覆盖的技术百科全书
目标读者:C# 开发者、Unity 游戏开发者、.NET 后端工程师、面试准备者、源码研究者


📖 为什么需要这个系列?

C# 是 .NET 生态和 Unity 游戏引擎的核心语言。然而大多数开发者「会用」却「不懂」——List<T> 扩容为什么是翻倍?Dictionary 的桶为什么是素数?Span<T> 为什么能做到零分配?foreach 为什么在 IL2CPP 下有 GC 陷阱?

这些问题背后,是 C# 语言设计的哲学、CLI 运行时的底层实现、以及数据结构源码的工程选择。

本系列从三个根出发,逐层深入:

覆盖内容
语言的根Anders Hejlsberg 的设计哲学、C# 1.0→12.0 版本演进全景、PME 组件模型
运行时的根CLI Runtime 架构、MethodTable 类型系统、JIT 编译管线、GC 三代回收
源码的根dotnet/runtime 仓库、System.Private.CoreLib、100% 覆盖所有 BCL 数据结构

🗺️ 篇章总览

C#与常用数据结构源码剖析/ ├── 00-全篇导览与书写计划/ (1篇) 系列总览与导览说明 ├── 01-运行时底层剖析/ (11篇) CLI Runtime 深度架构 ├── 02-历史与演化篇/ (6篇) C# 设计哲学与版本全景 ├── 03-数据结构-线性篇/ (5篇) Array / List<T> / LinkedList<T> / Span<T> ├── 04-数据结构-哈希与映射篇/ (7篇) Dictionary / HashSet / 哈希原理 ├── 05-数据结构-栈与队列篇/ (5篇) Stack<T> / Queue<T> / PriorityQueue<T> ├── 06-数据结构-排序集合篇/ (5篇) SortedSet / SortedDictionary / 红黑树 ├── 07-数据结构-并发集合篇/ (6篇) ConcurrentDictionary / ConcurrentQueue / BlockingCollection ├── 08-数据结构-不可变集合篇/ (4篇) ImmutableArray / ImmutableList / ImmutableDictionary ├── 09-数据结构-其他结构篇/ (5篇) Record / ValueTuple / BitArray / Collection / 非泛型遗产 ├── 10-高级特性实现原理篇/ (8篇) 泛型底层 / LINQ 源码 / async-await / 模式匹配 ├── 11-Unity实战篇/ (5篇) Mono vs IL2CPP / 热更新 / UniTask / 序列化 ├── 12-性能优化实战篇/ (3篇) GC 案例 / 装箱陷阱 / 生产案例 ├── 13-面试篇/ (7篇) 源码追问链 / 系统设计 / 代码审查 / 白板手写 ├── 14-演进与对比篇/ (5篇) C# vs Java/Go/Rust/UE、.NET 版本性能演进 ├── 15-实战工具篇/ (3篇) BenchmarkDotNet / Profiler / 内存分析 └── 16-附录/ (4篇) 术语表 / 源码索引 / 参考资源

🎯 推荐阅读路径

路径 A:快速了解(1-2 小时)

02-历史与演化篇(02-01,02-02) → 03-数据结构-线性篇(03-01,03-02) → 04-哈希与映射(04-01,04-03)

适合:快速建立 C# 核心数据结构认知。

路径 B:Unity 开发者(2-3 天)

02-历史与演化篇(概览) → 03-06 数据结构重点篇 → 11-Unity实战篇(全) → 12-性能优化(选读) → 13-面试篇(选读)

适合:需要在 Unity 项目中做好数据结构选型和性能优化的开发者。

路径 C:源码研究者(1-2 周)

01-运行时底层剖析(全) → 02-历史与演化(全) → 03-09 数据结构全部 → 10-高级特性(全)

适合:底层研究者、框架开发者、需要深度定制的场景。

路径 D:面试冲刺(1-2 天)

03-06 数据结构精读 → 10-高级特性(选读) → 13-面试篇(全)

适合:准备 .NET/C# 技术面试的开发者。

路径 E:全面精通(1-2 个月)

全部 90 篇文章,按编号顺序阅读

适合:希望成为 C# 领域专家的开发者。


📊 内容统计

维度数据
文章总数90 篇
篇章数量16 个
总字数(估算)~65 万中文字
C# 版本覆盖1.0 → 12.0,重点 9.0(Unity 官方支持)
源码基准版本.NET Framework 4.8 + .NET 6 + .NET 8 LTS(多版本对比)
数据结构覆盖率100%(~96 种 BCL 集合类型)
运行时覆盖CoreCLR + Mono 双运行时深度对比
Unity 版本覆盖Unity 2019.4 ~ Unity 6(6000.x)
源码仓库dotnet/runtime、dotnet/roslyn、mono/mono
生产案例8 个真实生产事故
Benchmark 数据40+ 组实测数据

📚 各篇章详解

00-全篇导览与书写计划(1 篇)— 系列导航

文件名核心内容
00-全篇导览系列总览、篇章地图、推荐阅读路径、内容统计

01-运行时底层剖析(11 篇)— CLI Runtime 从根说起

定位:在理解数据结构源码之前,先理解数据结构的"生存环境"——CLI 运行时如何编译、加载、执行、回收。

编号文件名核心内容源码位置
01-0101-运行时-C#代码如何变成机器码-编译与执行全链路Roslyn 编译 → IL → CoreCLR/Mono → JIT/AOT → 机器码dotnet/roslyn/src/Compilers/CSharp/
01-0201-运行时-MethodTable-一切类型的运行时身份证Object 头部布局、MethodTable 结构、EEClass 热/冷分离、值类型 vs 引用类型的运行时差异src/coreclr/vm/methodtable.h
01-0301-运行时-类型加载器-从IL元数据到运行时类型TypeLoader 分级加载、泛型共享(引用类型共享 EEClass)、TypeHandle/TypeDescsrc/coreclr/vm/class.cpp
01-0401-运行时-JIT编译管线-RyuJIT的完整阶段Importation → Inlining → Morph → SSA → VN → CSE → Range → Loop → Rationalization → Lowering → RA → CodeGensrc/coreclr/jit/
01-0501-运行时-JIT优化全景-内联去虚拟化边界检查消除Inlining 策略、Guarded Devirtualization、Range Check Elimination、Loop Cloning/Loop Unrollingsrc/coreclr/jit/rangecheck.cpp
01-0601-运行时-分层编译与PGO-运行时如何持续优化代码Tier0/Tier1 晋升策略、100ms 启动延迟 + 30 次调用计数器、Dynamic PGO 探针tiered-compilation.md
01-0701-运行时-GC深度剖析-内存分配回收与结构选择三代回收(Gen0/1/2)+ LOH + POH、Mark-Sweep-Compact 流程、写屏障(Write Barrier)、固定对象src/coreclr/gc/gc.cpp
01-0801-运行时-虚方法分派与接口调用的底层实现vtable 分派 vs VSD(Virtual Stub Dispatch)、接口调用的查找桩→分派桩→解析桩src/coreclr/vm/virtualcallstub.cpp
01-0901-运行时-Roslyn深度-从语法树到IL的编译魔法SyntaxTree → SemanticModel → BoundTree → Emit IL 完整链路dotnet/roslyn/src/Compilers/CSharp/
01-1001-运行时-AOT编译vsJIT-泛型反射代码生成的命运分野NativeAOT 的泛型处理、IL2CPP 的 AOT 限制、Reflection.Emit 的不可用原理src/coreclr/nativeaot/
01-1101-运行时-Mono运行时深度-与CoreCLR的类型系统与GC对决Mono 的 MonoClass/MonoMethod、SGen GC vs Boehm GC、Mini JIT vs RyuJIT、Unity 为什么还用 Boehmsrc/mono/

02-历史与演化篇(6 篇)— C# 从哪里来

定位:从 Anders Hejlsberg 的设计理念出发,理解每版 C# 为什么引入这些特性。

编号文件名核心内容
02-0102-历史-CSharp诞生记-Anders-Hejlsberg为什么要创造CSharpTurbo Pascal → Delphi → J++ → Cool 项目 → .NET;PME 属性-方法-事件组件模型;C# 对 C++/Java 的设计取舍
02-0202-历史-CSharp版本演化全景-上-1.0到4.0雏形→泛型(2.0)→LINQ革命(3.0)→动态编程(4.0);.NET Framework 1.0→4.0
02-0302-历史-CSharp版本演化全景-下-5.0到12.0async/await(5.0)→Roslyn开源(6.0)→性能与表达力(7.x)→空安全(8.0)→年更时代(9-12);.NET Core → .NET 5 → .NET 8 LTS
02-0402-历史-CSharp如何运行-从源码到执行的全链路C# src → Roslyn → IL DLL → CoreCLR/Mono Runtime → JIT/AOT → Native code;Assembly/Metadata/Module
02-0502-历史-CSharp的类型系统-值类型与引用类型的底层真相struct vs class 内存布局、装箱/拆箱全流程、ref struct 的零分配哲学、栈与堆
02-0602-历史-CSharp的GC机制-垃圾回收如何影响你的数据结构选择分代回收原理、Boehm vs SGen vs CoreCLR GC、GC 对 Unity 的影响、低 GC 编码技巧

03-数据结构-线性篇(5 篇)— Array / List<T> / LinkedList<T> / Span<T>

编号文件名核心内容
03-0103-线性-Array-一切集合的基石CLR 数组内存布局、SZArray 结构、多维 vs 交错数组、Array.Copy 内部实现、SZArrayHelper
03-0203-线性-List-T-最常用的动态数组到底做了什么_items[] + _size + _version 三板斧、扩容策略(默认4→翻倍)、TrimExcess 90% 阈值、Enumerator 版本检测、多版本对比(.NET 4.x → .NET 8)
03-0303-线性-LinkedList-T-双向链表的实现与选择困境LinkedListNode<T> 结构、为什么 List 通常比 LinkedList 快、CPU 缓存局部性、Unity 中何时用 LinkedList
03-0403-线性-Span-T-与Memory-T-零分配的高性能切片ref struct 限制、Span 的栈分配、.NET Core 字符串操作革命、Unity IL2CPP 下 Span 兼容性
03-0503-线性-综合对比-Array-vs-List-vs-LinkedList-vs-Span选型指南时间复杂度矩阵、内存占用实测、各平台 benchmark 数据、Unity 场景选型决策树

04-数据结构-哈希与映射篇(7 篇)— Dictionary / HashSet / 哈希原理

编号文件名核心内容
04-0104-哈希-Hash原理-为什么哈希表能做到O1查找GetHashCode 设计原则、取模优化(素数表+位运算)、链地址法 vs 开放寻址法、哈希碰撞攻击与防御
04-0204-哈希-Dictionary-TKey-TValue-上-核心数据结构_buckets[] + _entries[] 双数组设计、Entry 结构体、1-based 索引优化、_freeList/_freeCount 复用机制、初始容量素数选择
04-0304-哈希-Dictionary-TKey-TValue-下-关键操作逐行分析Add 完整流程(hash→取模→碰撞链→扩容)、Remove 的双链维护、FindValue 的 ref return、Resize 素数表、多版本对比(4.8→6→8)
04-0404-哈希-Dictionary-TKey-TValue-高级话题-自定义Comparer与序列化IEqualityComparer 正确实现、NonRandomizedStringEqualityComparer 防御、序列化与反序列化兼容性
04-0504-哈希-HashSet-T-基于Dictionary的无值哈希集合.NET 5 重写为基于 Dictionary 实现、Entry 去除 Key 字段、AddIfNotPresent JIT 去虚拟化、字符串比较器特殊处理
04-0604-哈希-OrderedDictionary-TKey-TValue-dotNET9全新有序字典哈希表+链表双重索引、按键 + 按索引双重访问、与 SortedDictionary 的本质区别
04-0704-哈希-综合对比-Dictionary-vs-SortedDictionary-vs-Hashtable-vs-OrderedDictionary时间复杂度矩阵、内存占用对比、特化型(StringDictionary/ListDictionary/HybridDictionary)

05-数据结构-栈与队列篇(5 篇)— Stack / Queue / PriorityQueue

编号文件名核心内容
05-0105-栈队列-Stack-T-LIFO的数组实现_array + _size 指针、Push/Pop 操作、扩容策略、Peek 边界检查
05-0205-栈队列-Queue-T-FIFO的环形数组实现_head/_tail 环绕指针、Dequeue 不清空引用的 GC 陷阱、TrimExcess、SetCapacity
05-0305-栈队列-PriorityQueue-TElement-TPriority-NET6最小堆实现四叉堆(d-ary heap)、Up/Down 筛选、Comparer 默认行为、UnorderedItems
05-0405-栈队列-Queue-vs-Stack-vs-Channel-T-不同场景的选择Channel<T> 生产者-消费者、ConcurrentQueue 无锁实现概述、Unity 异步场景选型
05-0505-栈队列-ArrayPool-T-与MemoryPool-T-高性能内存池ArrayPool.Shared.Rent/Return 实现、TlsOverPerCoreLockedStacks 策略、MemoryPool 设计

06-数据结构-排序集合篇(5 篇)— SortedSet / SortedDictionary / 红黑树

编号文件名核心内容
06-0106-排序集合-红黑树原理-SortedSet与SortedDictionary背后的数据结构红黑树五大性质、左旋右旋图解、插入修复 6 种 case、与 AVL 树对比
06-0206-排序集合-SortedSet-T-红黑树源码逐行剖析Node 结构(Item/Left/Right/IsRed)、AddIfNotPresent 递归插入、双指针维护父子、Min/Max/GetViewBetween
06-0306-排序集合-SortedDictionary-TKey-TValue-排序的键值对集合与 SortedSet 共享 TreeSet<T> 底层、KeyCollection/ValueCollection 懒加载、SortedList 数据结构差异
06-0406-排序集合-SortedList-TKey-TValue-双数组实现的有序集合keys[] + values[] 双数组、二分查找插入、O(n)插入 vs O(log n)查找 抉择、读多写少场景优势
06-0506-排序集合-综合对比-SortedSet-vs-SortedDictionary-vs-SortedList选型时间复杂度矩阵、内存布局对比、各场景最优选型、Unity 实战案例

07-数据结构-并发集合篇(6 篇)— Concurrent / BlockingCollection / Channel

定位:从线程安全角度理解所有并发数据结构——细粒度锁、CAS 无锁算法、工作窃取。

编号文章名核心内容
07-01ConcurrentDictionary:线程安全的哈希表细粒度桶锁+CAS、Volatile Tables 切换、GetOrAdd 双重检查锁定、与 lock(Dictionary) 多维度 Benchmark
07-02ConcurrentQueue:链表 Segment 无锁 FIFOSegment 链表结构、32槽位设计权衡、Interlocked CAS 入队/出队、SpinWait 退避策略
07-03ConcurrentStack:无锁链式栈的 CAS 魔法单向链表+CAS Push/Pop、ABA 问题 GC 天然规避、PushRange/TryPopRange 批量操作、SpinWait 详细
07-04ConcurrentBag:工作窃取(Work-Stealing)算法ThreadLocal + _head/_tail 两端操作、本地无锁、窃取 Interlocked、适用场景
07-05BlockingCollection 与 Channel:生产者-消费者利器BoundedChannel 背压机制、同步阻塞 vs 异步管道、Reader/Writer 分离模式
07-06并发集合综合对比六种并发集合全面对比 + 选型决策树 + 常见错误场景清单

08-数据结构-不可变集合篇(4 篇)— Immutable / 持久化数据结构

定位:持久化数据结构的设计哲学——每次修改创建新版本,共享未修改节点。

编号文章名核心内容
08-01ImmutableArray<T>:零开销不可变结构体struct 包装 T[]、默认零分配、Builder 批量构造、与 T[] 的性能对比
08-02ImmutableList<T>:持久化 AVL 树实现每次修改 O(log n) 新节点、节点共享内存图示(百万级 99.998% 共享)、Builder 模式
08-03ImmutableDictionary / HashSet:CHAMP 哈希树CHAMP 位图压缩编码、32路分支 popcount 索引、每次修改 O(log₃₂ n) 新节点
08-04ImmutableStack/Queue + Builder 模式总结ImmutableStack 共享节点链表、ImmutableQueue 双栈设计、Builder+ImmutableInterlocked

09-数据结构-其他结构篇(5 篇)— 剩余类型全覆盖

编号文章名核心内容
09-01Record:不可变数据容器record class vs struct、with 表达式编译器生成 Clone、与不可变集合协同
09-02ValueTuple 与解构struct 零分配 vs Tuple class、命名元组编译器翻译、Deconstruct 模式
09-03BitArray 与 BitVector32:位级别数据结构BitArray int[] 存储 32x 内存节省、BitVector32 单 int 紧凑编码、Section 切分
09-04Collection / ObservableCollection / KeyedCollection可扩展基类模式、INotifyCollectionChanged UI 绑定、双存储自适应切换
09-05非泛型集合遗产:ArrayList / Hashtable装箱代价 Benchmark(48x 差距)、Hashtable 线程安全假象、HybridDictionary 自适应设计

10-高级特性实现原理篇(8 篇)— 从数据结构到语言特性

编号文章名核心内容
10-01泛型底层实现:Reified vs Type ErasureJIT 值类型特化、引用类型代码共享、constrained 前缀 IL 分析、与 Java/ArrayList 多维 Benchmark
10-02LINQ 源码剖析(上):Where/Select/SelectMany三种特化迭代器、yield return 状态机展开、SelectMany 展平
10-03LINQ 源码剖析(下):GroupBy/Join/Aggregate/IQueryable内部 Dictionary 分组、哈希连接、Expression Tree 翻译原理
10-04async/await 编译器魔法AsyncStateMachine 完整展开、struct vs class 状态机、ValueTask 零分配、ConfigureAwait 死锁避免
10-05模式匹配:C# 7-12 演进类型/属性/关系/逻辑/列表 5 种模式、编译器降级 if-else、穷尽性检查
10-06unsafe 代码与指针fixed/pinned 变量 IL、stackalloc、delegate* 函数指针 Benchmark(2.2x 快)
10-07反射与源生成器MethodInfo.Invoke 400x 慢对比、Source Generators 替代方案、选型原则
10-08属性/事件/委托/运算符的编译器翻译get_/set_ 方法对、add_/remove_、MulticastDelegate 不可变性、op_Addition IL 名

11-Unity实战篇(5 篇)— Unity 中的 C# 落地

编号文章名核心内容
11-01Unity 中的 C# 实战全景Unity 6 C# 9.0 支持、Mono vs IL2CPP 差异矩阵、5 条黄金法则、Job System + Burst
11-02Mono vs IL2CPP:运行时差异分析JIT vs AOT 泛型陷阱、link.xml 修复、GC 行为差异(Boehm vs IL2CPP)
11-03List<T> 和 Dictionary 在 Unity 中的性能调优预分配 Capacity、对象池化、String key 替代 enum/int
11-04Span 与零分配、foreach/LINQ 陷阱Span 零分配 CSV 解析、foreach 接口装箱根因(编译器规则)、Profiler 实测对比
11-05热更新/Job System/UniTask/序列化综合HybridCLR vs link.xml、DOTS 数据结构对比 BCL、UniTask struct 设计、SerializedDictionary

12-性能优化实战篇(3 篇)— 案发现场还原式 + 生产案例

编号文章名核心内容
12-01性能分析全景:四步法 + 案例 + Unity 专项Measure→Locate→Optimize→Verify、接口去虚拟化损失、struct 在泛型集合装箱、LOH BGC 阻塞案例、ConcurrentDictionary GC 暂停对比
12-02案发现场 1-7:数据结构性能罪案实录7 个案发现场(含 2 个真实生产案例):无界 Dictionary OOM、EventHandler 泄漏、StringComparer 选择、LOH 碎片
12-03GC/装箱/内存池化/SIMD Benchmark 合集LOH 碎片 Benchmark、装箱 74x 差距、SIMD 4x 加速、对象池 12x 加速、StringComparer Ordinal vs Invariant 案例分析

13-面试篇(7 篇)— 链式追问体系

编号文章名核心内容
13-00面试篇概要10 大面试主题速查表
13-01基础概念链式追问值/引用类型、装箱拆箱、List 扩容、Dictionary O(1)、foreach 陷阱
13-02数据结构逐层深问(七层)Array→List→Dict→SortedDict→Concurrent→Immutable 七层递进
13-03算法实现追问完整手写 LRU/线程安全队列 CAS/最小堆 Up+Down/SkipList(含追问)
13-04源码级深度追问链Resize 素数选择、_freeList 编码、HashSet 重写、Span ref struct、ABA 规避
13-05语言设计哲学追问struct 存在理由、reified vs erasure、ref struct 约束、Record 选择
13-06IL底层+系统设计+代码审查+选型+白板手写10 条找茬清单、生产排查工具箱、对比选型表

14-演进与对比篇(5 篇)— 跨语言/跨版本对比

编号文章名核心内容
14-00演进与对比篇概要4 篇内容速览
14-01.NET 各版本性能演进List/Dictionary/HashSet 版本变更表、.NET 8 Vector256 源码、ConcurrentDictionary PR 追溯
14-02C# vs Java 数据结构对比泛型 reified vs erasure、素数桶 vs 2幂桶+树化、并发结构、多维度 Benchmark 数据
14-03C# vs Go vs Rust 内存模型GC vs 所有权、Span vs Slice、泛型对比、7 项 Benchmark 同算法对比
14-04Unity vs Unreal 引擎数据结构对比C# vs C++ STL、GC 影响、DOTS vs UE ECS、Data-Oriented Design

15-实战工具篇(3 篇)— 兵器谱

编号文章名核心内容
15-01BenchmarkDotNet 深度使用指南基本配置、数据结构模板、陷阱(死代码消除/GC 干扰/静态污染)、结果解读
15-02Unity Profiler 与 Memory Profiler 实战Profiler 窗口全解、快照对比流程、常见问题清单(Dictionary/事件/协程)、真机连接
15-03dotMemory 与 PerfView:生产环境内存分析dotMemory 排查流程、PerfView GCStats 健康值、SOS 命令(dumpheap/gcroot/dumpgen)

16-附录(4 篇)— 速查表

编号文章名核心内容
16-00附录概要工具篇和附录内容索引
16-01术语表33 个核心术语(CLI/IL/JIT/AOT/GC/SSA/VN/VSD/LOH/POH/ref struct/Span/boxing)
16-02源码索引速查25 个数据结构源码路径 + 运行时源码路径 + .NET 版本 tag 表 + 5 个关键 PR 链接
16-03参考资源官方文档 / GitHub 仓库 / 4 本必读书 / 5 个社区工具 / 性能工具链接

最后更新:2026-07-18
维护状态:持续更新,跟随 .NET LTS 版本演进
参考仓库:dotnet/runtime · dotnet/roslyn · Unity 官方文档

← 返回列表