首先,我们以“创建一个简单的、未实现泛型的、能包含任何类型的链表类”作为切入点;然后我们再对其改装成支持泛型的列表类。
我们都知道“链表”内部总是一个元素连接到下一个元素,所以我们需要创建一个类来表示其中的每一个节点。这个节点类,需要包含三个信息:1.之前的节点 2.本节点 3.之后的节点。
基于以上的分析,我们得到了节点类LinkedListNode:
View Code
public class LinkedListNode { public object Value { get; private set; } public LinkedListNode(object value) { Value = value; } public object Prev { get; internal set; } public object Next { get; internal set; } }
class LinkedList:IEnumerable { public LinkedListNode First { get;private set; } public LinkedListNode Last { get; private set; } public LinkedListNode AddLast(object node) { LinkedListNode newNode = new LinkedListNode(node); if (First == null)//如果链表为空 { First = newNode; Last = First; } else { Last.Next = newNode; Last = newNode; } return newNode; } public IEnumerator GetEnumerator() { LinkedListNode current = First; while (current != null) { yield return current.Value; current = current.Next; } } }
以下,我们对其添加新节点。可以看出几个问题:1.addLast(值类型)时,涉及到装箱过程(int->object) 2.没有类型安全:list1.AddLast(“6”); 3.foreach (int i in list1)中,涉及到拆箱过程(object -> int)
LinkedList list1 = new LinkedList(); list1.AddLast(2); list1.AddLast(4); list1.AddLast(“6”); foreach (int i in list1) { Console.WriteLine(i); }
现在我们对上诉两个类进行改装,使其成为支持泛型的类:
public class LinkedListNode{ public T Value { get; private set; } public LinkedListNode(T value) { Value = value; } public T Prev { get; internal set; } public T Next { get; internal set; } }
class LinkedList: IEnumerable { public LinkedListNode First { get;private set; } public LinkedListNode Last { get; private set; } public LinkedListNode AddLast(T node) { LinkedListNode newNode = new LinkedListNode (node); if (First == null)//如果链表为空 { First = newNode; Last = First; } else { Last.Next = newNode; Last = newNode; } return newNode; } public IEnumerator GetEnumerator() { LinkedListNode current = First; while (current != null) { yield return current.Value; current = current.Next; } } }
LinkedList < int > list2 = new LinkedList < int > (); list2.AddLast(1); list2.AddLast(3); list2.AddLast(5); foreach (int i in list2) { Console.WriteLine(i); }
现在使用以上代码,将不会有装箱、拆箱过程中的性能损失。同时还是类型安全的,如果foreach (int i in list2)中声明的不是int,那么编译期间就会报错。