.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>( 四 )


这三个属性在此处似乎只有定义,并没有在其他地方调用,推测其作用是作为该对象的一种标识属性,在进行某些操作时,供 CLR 检测访问是否允许执行该操作 。
【注:碍于篇幅,后两个属性将在之后的文章进行补充说明】
(三) 五个字段

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
  • Line 701:_list 表示当前的链表对象,仅用于内部访问 。
  • Line 704:_node 表示链表中的每个结点 。其内部包含:结点所在的链表、该结点的下一个结点与上一个结点、当前结点存储的值 。
  • Line 707:_version 执行修改操作的次数 。
  • Line 710:_current 用于在枚举器中,记录当前所在的结点 。
  • Line 713:_index 用于在枚举器中,记录当前结点所对应的索引值 。
(四) 一个结构 -> 迭代器 or 枚举器1.    结构体的构造方法
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
初始化内部字段,为之后的迭代器遍历与结点做准备 。
2.    两个属性
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
  • Line 625:Current属性,返回当前所指向的结点 。
  • Line 637:IEnumerator.Current属性 , 迭代过访问程中 , 若存在还未访问到的元素,则返回当前迭代器所指向的对象 。
3.    MoveNext()方法
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
将指向当前结点对象的引用,向后移动到下一个结点 。配合迭代器访问,逐一向后遍历元素 。
  • Line 652:若两个 version 不相同,无法执行操作 。在文章([数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习) - PaperHammer - 博客园 (cnblogs.com))中,简要分析了 version 在ArrayList 中的作用 , 在执行某些操作后 , 会使版本号+1 。主要是一些会修改集合内部元素的操作 。因此 version 可以是做是一个集合的标识符 。
在枚举器的构造方法里,已将 _list.version 赋值给 version,理论上每次进行枚举迭代均会更新 version 。因此该判断语句的目的可能是防止经过浅层拷贝的两个集合,在职u型某些操作后,调用另一个不属于自身的迭代器 。
【有关浅层拷贝请参阅([数据结构1.1-线性表] 数组 (.NET源码学习) - PaperHammer - 博客园 (cnblogs.com))】
  • Line 656:若 node 为 null , 说明没有元素可以继续向下访问,则返回 false 。
  • Line 661~663:index 指针向后移动;_current 记录当前结点;访问下一个结点 。
  • Line 664:若再次访问到头结点,则终止 。
4.    Reset()方法
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
在每次调用完枚举器后,需要恢复原有的信息,以便下一次继续调用 。可以理解为回溯 。
【注:有关迭代器的实现原理,会在文末进行补充说明】
(五) 常用方法1.    添加 AddFirst()、AddLast() 与 AddBefore()、AddAtfer()首先是方法 AddFirst() 。其有两个重载方法,不同之处体现在返回值类型与参数 。
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
  • Line 156:返回类型为某一结点,参数为某一值 。
  • Line 161:若头结点为空,说明当前链表内没有结点,则调用方法InternalInsertNodeToEmptyList() 。

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
该方法的作用是:在空表中创建一个结点,其既是头结点,也是尾结点 。
  • Line 165:若头结点不为空,说明此时表中已经存在节点,则调用方法InternalInsertNodeBefore(),将新结点加入到当前头结点之前 , 成为新的头结点 。

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
  • Line 168、184:最终的返回结果/指向是头结点 。
—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——
方法 AddLast() 与 AddFirst() 大同小异,在此不做过多分析
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图