.NET自从2.0版本开始就支持泛型。
- 非泛型链表
闲话休提,马上来看下非泛型的简化链表类,它可以包含任意类型的对象。
LinkedListNode.cs中:
在链表中,一个元素引用另一个元素,所以必须创建一个类,将其封装在链表中,并引用下一个对象。
1 public class LinkedListNode 2 { 3 public LinkedListNode(object value) 4 { 5 this.Value = value; 6 } 7 8 public object Value { get; private set; } 9 10 public LinkedListNode Next { get; internal set; } 11 public LinkedListNode Prev { get; internal set; } 12 }
LinkedListNode.cs中:
LinkedList类包含LinkedListNode类型的First,与Last属性,它们分别标志了链表的头尾。通过实现GetEnumerator()方法,可以用foreach语句遍历链表。
1 public class LinkedList : IEnumerable 2 { 3 public LinkedListNode First { get; private set; } 4 public LinkedListNode Last { get; private set; } 5 6 public LinkedListNode AddLast(object node) 7 { 8 var newNode = new LinkedListNode(node); 9 if (First == null) 10 { 11 First = newNode; 12 Last = First; 13 } 14 else 15 { 16 Last.Next = newNode; 17 Last = newNode; 18 } 19 return newNode; 20 } 21 22 public IEnumerator GetEnumerator() 23 { 24 LinkedListNode current = First; 25 while (current != null) 26 { 27 yield return current.Value; 28 current = current.Next; 29 } 30 }
Program.cs中:
1 var list1 = new LinkedList(); 2 list1.AddLast(2); 3 list1.AddLast(4); 4 list1.AddLast("6"); 5 6 foreach (int i in list1) 7 { 8 Console.WriteLine(i); 9 }
此时,会出现一个运行异常,因为把链表中第3个元素转换成整形时会出现异常。
- 泛型链表
为了避免这种情况,下面创建泛型的链表。
LinkedListNode.cs中:
LinkedListNode类用一个泛型类型T声明。属性Value的类型是The,而不是object.
public class LinkedListNode<T> { public LinkedListNode(T value) { this.Value = value; } public T Value { get; private set; } public LinkedListNode<T> Next { get; internal set; } public LinkedListNode<T> Prev { get; internal set; } }
LinkedList.cs中:
也把LinkedList定义成泛型类。
1 public class LinkedList<T> : IEnumerable<T> 2 { 3 public LinkedListNode<T> First { get; private set; } 4 public LinkedListNode<T> Last { get; private set; } 5 6 public LinkedListNode<T> AddLast(T node) 7 { 8 var newNode = new LinkedListNode<T>(node); 9 if (First == null) 10 { 11 First = newNode; 12 Last = First; 13 } 14 else 15 { 16 Last.Next = newNode; 17 Last = newNode; 18 } 19 return newNode; 20 } 21 22 public IEnumerator<T> GetEnumerator() 23 { 24 LinkedListNode<T> current = First; 25 26 while (current != null) 27 { 28 yield return current.Value; 29 current = current.Next; 30 } 31 } 32 33 IEnumerator IEnumerable.GetEnumerator() 34 { 35 return GetEnumerator(); 36 } 37 }
Program.cs中:
1 class Program 2 { 3 static void Main() 4 { 5 var list2 = new LinkedList<int>(); 6 list2.AddLast(1); 7 list2.AddLast(3); 8 list2.AddLast(5); 9 10 foreach (int i in list2) 11 { 12 Console.WriteLine(i); 13 } 14 15 var list3 = new LinkedList<string>(); 16 list3.AddLast("2"); 17 list3.AddLast("four"); 18 list3.AddLast(null); 19 20 foreach (string s in list3) 21 { 22 Console.WriteLine(s); 23 } 24 Console.Read(); 25 26 }
现在foreach是类型安全的了。