泛型概述, 创建泛型类

来源:互联网 发布:john frusciante 知乎 编辑:程序博客网 时间:2024/06/07 23:00

   在.NET 1.0中,要创建一个灵活的类或方法,但该类或方法在编译期间不知道使用什么类,就必须以Object类为基础。而Object类在编译期间没有类型安全性,因此必须进行强制类型转换。另外,给值类型使用Object类会有性能损失。
.NET 2.0提供了泛型。有了泛型,就不再需要Object类了。泛型类使用泛型类型,并可以根据需要用特定的类型替换泛型类型。这就保证了类型安全性:如果某个类型不支持泛型类,编译器就会生成错误。
泛型概述:
泛型的一个主要优点是性能。
泛型的另一个特性是类型安全。
二进制代码的重用.泛型允许更好地重用二进制代码。泛型类可以定义一次,用许多不同的类型实例化。
代码的扩展.
在用不同的类型实例化泛型时,会创建多少代码?
命名约定.  泛型类型的名称用字母T作为前缀;如果没有特殊的要求,泛型类型允许用任意类替代,且只使用了一个泛型类型,就可以用字符T作为泛型类型的名称;  如果泛型类型有特定的要求(例如必须实现一个接口或派生于基类),或者使用了两个或多个泛型类型,就应给泛型类型使用描述性的名称.


下面创建链表的泛型版本。

 

泛型类的定义与一般类类似,只是要使用泛型类型声明。之后,泛型类型就可以在类中用作一个字段成员,或者方法的参数类型。LinkedListNode类用一个泛型类型T声明。字段value的类型是T,而不是object。构造函数和Value属性也变为接受和返回T类型的对象。也可以返回和设置泛型类型,所以属性Next和Prev的类型是LinkedListNode<T>。

 

  1. public class LinkedListNode<T>
  2. {
  3. private T value;
  4. public LinkedListNode(T value)
  5. {
  6. this.value = value;
  7. }
  8. public T Value
  9. {
  10. get { return value; }
  11. private LinkedListNode<T> next;
  12. public LinkedListNode<T> Next
  13. {
  14. get { return next; }
  15. internal set { next = value; }
  16. }
  17. private LinkedListNode<T> prev;
  18. public LinkedListNode<T> Prev
  19. {
  20. get { return prev; }
  21. internal set { prev = value; }
  22. }
  23. }

LinkedList类包含LinkedListNode类型的first和last字段,它们分别标记了链表的头尾。AddLast()方法在链表尾添加一个新元素。首先创建一个LinkedListNode类型的对象。如果链表是空的,则first和last字段就设置为该新元素;否则,就把新元素添加为链表中的最后一个元素。执行GetEnumerator()方法时,可以用foreach语句迭代链表。GetEnumerator()方法使用yield语句创建一个枚举器类型。

在.NET 2.0推出后,IEnumerable接口也有一个泛型版本IEnumerable<T>IEnumerable<T>派生IEnumerable,添加了返回IEnumerator<T>的GetEnumerator()方法,LinkedList<T>执行泛型接口IEnumerable<T>。

 

  1. public class LinkedList<T> : IEnumerable<T>
  2. {
  3. private LinkedListNode<T> first;
  4. public LinkedListNode<T> First
  5. {
  6. get { return first; }
  7. }
  8. private LinkedListNode<T> last;
  9. public LinkedListNode<T> Last
  10. {
  11. get { return last; }
  12. }
  13. public LinkedListNode<T> AddLast(T node)
  14. {
  15. LinkedListNode<T> newNode = new LinkedListNode<T>(node);
  16. if (first == null)
  17. {
  18. first = newNode;
  19. last = first;
  20. }
  21. else
  22. {
  23. last.Next = newNode;
  24. last = newNode;
  25. }
  26. return newNode;
  27. }
  28. public IEnumerator<T> GetEnumerator()
  29. {
  30. LinkedListNode<T> current = first;
  31. while (current != null)
  32. {
  33. yield return current.Value;
  34. current = current.Next;
  35. }
  36. }
  37. IEnumerator IEnumerable.GetEnumerator()
  38. {
  39. return GetEnumerator();
  40. }
  41. }

    使用泛型类LinkedList<T>,可以用int类型实例化它,且无需装箱操作。如果不使用AddLast()方法传送int,就会出现一个编译错误。使用泛型IEnumerable<T>,foreach语句也是类型安全的,如果foreach语句中的变量不是int,也会出现一个编译错误。
LinkedList<int> list2 = new LinkedList<int>();
list2.AddLast(1);
list2.AddLast(3);
list2.AddLast(5);
foreach (int i in list2)
{
Console.WriteLine(i);
}
   同样,可以给泛型LinkedList<T>使用string类型,将字符串传送给AddLast()方法。
LinkedList<string> list3 = new LinkedList<string>();
list3.AddLast("2");
list3.AddLast("four");
list3.AddLast("foo");
foreach (string s in list3)
{
Console.WriteLine(s);
}

 



原创粉丝点击