这三个属性在此处似乎只有定义,并没有在其他地方调用,推测其作用是作为该对象的一种标识属性,在进行某些操作时,供 CLR 检测访问是否允许执行该操作 。
【注:碍于篇幅,后两个属性将在之后的文章进行补充说明】
(三) 五个字段
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://pic.ikafan.com/imgp/L3Byb3h5L2h0dHBzL2ltZzIwMjIuY25ibG9ncy5jb20vYmxvZy8yODUxNTQwLzIwMjIxMS8yODUxNTQwLTIwMjIxMTA4MTM1MDA0NzIyLTE0ODQ4NDExMjUucG5n.jpg)
文章插图
- Line 701:_list 表示当前的链表对象,仅用于内部访问 。
- Line 704:_node 表示链表中的每个结点 。其内部包含:结点所在的链表、该结点的下一个结点与上一个结点、当前结点存储的值 。
- Line 707:_version 执行修改操作的次数 。
- Line 710:_current 用于在枚举器中,记录当前所在的结点 。
- Line 713:_index 用于在枚举器中,记录当前结点所对应的索引值 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K64253c-22.png)
文章插图
初始化内部字段,为之后的迭代器遍历与结点做准备 。
2. 两个属性
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6422201-23.png)
文章插图
- Line 625:Current属性,返回当前所指向的结点 。
- Line 637:IEnumerator.Current属性 , 迭代过访问程中 , 若存在还未访问到的元素,则返回当前迭代器所指向的对象 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6423306-24.png)
文章插图
将指向当前结点对象的引用,向后移动到下一个结点 。配合迭代器访问,逐一向后遍历元素 。
- Line 652:若两个 version 不相同,无法执行操作 。在文章([数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习) - PaperHammer - 博客园 (cnblogs.com))中,简要分析了 version 在ArrayList 中的作用 , 在执行某些操作后 , 会使版本号+1 。主要是一些会修改集合内部元素的操作 。因此 version 可以是做是一个集合的标识符 。
【有关浅层拷贝请参阅([数据结构1.1-线性表] 数组 (.NET源码学习) - PaperHammer - 博客园 (cnblogs.com))】
- Line 656:若 node 为 null , 说明没有元素可以继续向下访问,则返回 false 。
- Line 661~663:index 指针向后移动;_current 记录当前结点;访问下一个结点 。
- Line 664:若再次访问到头结点,则终止 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K64225B-25.jpg)
文章插图
在每次调用完枚举器后,需要恢复原有的信息,以便下一次继续调用 。可以理解为回溯 。
【注:有关迭代器的实现原理,会在文末进行补充说明】
(五) 常用方法1. 添加 AddFirst()、AddLast() 与 AddBefore()、AddAtfer()首先是方法 AddFirst() 。其有两个重载方法,不同之处体现在返回值类型与参数 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6426221-26.png)
文章插图
- Line 156:返回类型为某一结点,参数为某一值 。
- Line 161:若头结点为空,说明当前链表内没有结点,则调用方法InternalInsertNodeToEmptyList() 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6423293-27.png)
文章插图
该方法的作用是:在空表中创建一个结点,其既是头结点,也是尾结点 。
- Line 165:若头结点不为空,说明此时表中已经存在节点,则调用方法InternalInsertNodeBefore(),将新结点加入到当前头结点之前 , 成为新的头结点 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K64244F-28.jpg)
文章插图
- Line 168、184:最终的返回结果/指向是头结点 。
方法 AddLast() 与 AddFirst() 大同小异,在此不做过多分析
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K642D06-29.png)
文章插图
- Line 199、214:执行完毕后 , 返回/指向的结点是尾结点 。
推荐阅读
- MPC:百万富翁问题
- Redisson源码解读-公平锁
- 重新整理 .net core 实践篇 ———— dotnet-dump [外篇]
- PGL Paddle Graph Learning 关于图计算&图学习的基础知识概览:前置知识点学习
- .Net 7里的函数.Ctor和.CCtor是干啥用的呢?你知道吗
- OpenHarmony移植案例: build lite源码分析之hb命令__entry__.py
- 【深入浅出 Yarn 架构与实现】1-2 搭建 Hadoop 源码阅读环境
- 关于ASP.NET Core WebSocket实现集群的思考
- .NET周报【11月第1期 2022-11-07】
- JVM学习笔记——内存模型篇