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


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

文章插图

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

文章插图
注意,由于 ArrayList 内部存储的元素并不是同一个类型,因此其并未继承泛型接口 IEnumerable<T>,其只继承了普通接口 IEnumerable,因此不能将其通过构造函数直接转化为链表 。
  • Line 36:传入了一个对象进行序列化或反序列化所需的全部数据,将这些数据赋值给字段 _siInfo 。contest 表示该对象的数据流的信息,作用是说明给定序列化流的源和目标,并提供另一个调用方定义的上下文 。
(二) 六个属性1.    Count
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
只读属性,返回链表长度 。
2.    First
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
只读属性,返回链表头结点,若不存在则根据特性 Nullable 返回空 。每个数字对应修饰的对象,此处 2表示可为空,对应 Linkedlist;1表示不能为空,对应 <T> 。
一般地,被 Nullable 修饰的变量可以为空 。以 Nullable 作为特性,可以修饰方法、属性等,拓宽了数据可为空的范围 。
3.    Last
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
只读属性,返回链表尾结点 。因为LinkedList 默认是双向链表,因此 tail == head.prev 。
4.    IsReadOnly、IsSynchronized与SyncRoot注:这三个属性为非公共属性,只限于类自己内部调用 。
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
只读属性,分别表示 LinkedList 的非只读、对堆栈的访问不同步 (线程安全)、获取可用于同步对 ICollection 的访问的对象 。其中,符号<!0>可能表示非 NULL
这三个属性在此处似乎只有定义,并没有在其他地方调用,推测其作用是作为该对象的一种标识属性,在进行某些操作时,供 CLR 检测访问是否允许执行该操作 。
【注:碍于篇幅,后两个属性将在之后的文章进行补充说明】
(三) 五个字段
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

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

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

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

文章插图
将指向当前结点对象的引用,向后移动到下一个结点 。配合迭代器访问,逐一向后遍历元素 。

经验总结扩展阅读