正文

.Net3.0 泛型 系列理论[2]2008-08-13 11:35:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/yzrj/37550.html

分享到:

9.2  创建泛型类 首先介绍一个一般的、非泛型的简化链表类,它可以包含任意类型的对象,以后再把这个类转化为泛型类。 在链表中,一个元素引用其后的下一个元素。所以必须创建一个类,将对象封装在链表中,引用下一个对象。类LinkedListNode包含一个对象value,它用构造函数初始化,还可以用Value属性读取。另外,LinkedListNode类包含对链表中下一个元素和上一个元素的引用,这些元素都可以从属性中访问。 public class LinkedListNode { private object value; public LinkedListNode(object value) { this.value = value; } public object Value { get { return value; } }   private LinkedListNode next; public LinkedListNode Next { get { return next; } internal set { next = value; } }   private LinkedListNode prev; public LinkedListNode Prev { get { return prev; } internal set { prev = value; } } } LinkedList类包含LinkedListNode类型的first和last字段,它们分别标记了链表的头尾。AddLast()方法在链表尾添加一个新元素。首先创建一个LinkedListNode类型的对象。如果链表是空的,则first和last字段就设置为该新元素;否则,就把新元素添加为链表中的最后一个元素。执行GetEnumerator()方法时,可以用foreach语句迭代链表。GetEnumerator()方法使用yield语句创建一个枚举器类型。 提示: yield语句参见第5章。 public class LinkedList : IEnumerable { private LinkedListNode first; public LinkedListNode First { get { return first; } }   private LinkedListNode last; public LinkedListNode Last { get { return last; } }   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; } } } 现在可以给任意类型使用LinkedList类了。在下面的代码中,实例化了一个新LinkedList对象,添加了两个整数类型和一个字符串类型。整数类型要转换为一个对象,所以执行装箱操作,如前面所述。在foreach语句中执行拆箱操作。在foreach语句中,链表中的元素被强制转换为整数,所以对于链表中的第三个元素,会发生一个运行异常,因为它转换为int时会失败。 LinkedList list1 = new LinkedList(); list1.AddLast(2); list1.AddLast(4); list1.AddLast("6"); foreach (int i in list1) { Console.WriteLine(i); } 下面创建链表的泛型版本。泛型类的定义与一般类类似,只是要使用泛型类型声明。之后,泛型类型就可以在类中用作一个字段成员,或者方法的参数类型。LinkedListNode类用一个泛型类型T声明。字段value的类型是T,而不是object。构造函数和Value属性也变为接受和返回T类型的对象。也可以返回和设置泛型类型,所以属性Next和Prev的类型是LinkedListNode<T>。 public class LinkedListNode<T> { private T value; public LinkedListNode(T value) { this.value = value; }   public T Value { get { return value; } }   private LinkedListNode<T> next; public LinkedListNode<T> Next { get { return next; } internal set { next = value; } }   private LinkedListNode<T> prev; public LinkedListNode<T> Prev { get { return prev; } internal set { prev = value; } } } LinkedList类也改为泛型类。LinkedList<T>包含LinkedListNode<T>元素。LinkedList中的类型T定义了类型T的包含字段first和last。AddLast()方法现在接受类型T的参数,实例化LinkedListNode<T>类型的对象。 在.NET 2.0推出后,IEnumerable接口也有一个泛型版本IEnumerable<T>。IEnumerable<T>派生于IEnumerable,添加了返回IEnumerator<T>的GetEnumerator()方法,LinkedList<T>执行泛型接口IEnumerable<T>。 提示: 枚举、接口IEnumerable和IEnumerator详见第5章。 public class LinkedList<T> : IEnumerable<T> { private LinkedListNode<T> first; public LinkedListNode<T> First { get { return first; } }   private LinkedListNode<T> last; public LinkedListNode<T> Last { get { return last; } }   public LinkedListNode<T> AddLast(T node) { LinkedListNode<T> newNode = new LinkedListNode<T>(node); if (first == null) { first = newNode; last = first; } else { last.Next = newNode; last = newNode; } return newNode; }   public IEnumerator<T> GetEnumerator() { LinkedListNode<T> current = first; while (current != null) { yield return current.Value; current = current.Next; } }   IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } 使用泛型类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); } 提示: 每个处理对象类型的类都可以有泛型实现方式。另外,如果类使用了继承,泛型非常有助于去除类型转换操作。

阅读(1731) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册