泛型(三)泛型类型和继承

泛型类型仍然是类型,所以它能从其他任何类型派生,使用一个泛型类型并指定类型实参时,实际是在CLR中定义一个新的类型对象,新的类型对象是从泛型类型派生自的那个类型派生的,换言之,由于List<T>是从Object派生的,所以List<String>和List<Guid>也从Object派生。
 
类似地,由于DictionaryStringKey<TValue>派生自Dictionary<String,TValue>所以DictionaryStringKey<Guid>派生自Dictionary<String,Guid>,类型实参的指定和继承层次结构没有任何关系--理解这一点,有助于判断哪些转型是能够进行的,哪些转型是不能进行的。
 
继承
 

假定像下面这样定义一个链表节点类

internal sealed class Node<T>{
    
    public T m_data;
    public Node<T> m_next;
    
    public Node(T data):this(data,null){}
    
    public Node(T data,Node<T> next){
        m_data=data;
        m_next=next;
    }
    
    public override ToString(){
        return m_data.ToString()+
            ((m_next!=null)?m_next.ToString():null);
    }

}

static void Main(string[] args)
{
    Node<Char> head = new Node<Char>('C');
    head = new Node<Char>('B', head);
    head = new Node<Char>('A', head);
    Console.WriteLine(head.ToString());
}

输出:ABC

 

在这个Node类中,对于m_next字段引用的另一个节点来说,它的m_data字段必须包含相同的数据类型,意味着在链表包含的节点中,所有数据项都必须具有相同的类型(或派生类型),不能包含即有DateTime类型又有String 类型
 
改进
 
思路:定义一个非泛型的Node基类,在定义一个泛型TypedNode类(用Node类作为基类),这样依赖就可以创建一个链表,每个节点都可以是一种具体的数据类型(非Object类型),同时防止装箱,有点递归的意思。
 internal  class Node{
        protected Node m_next;
        public Node(Node next) {
            m_next = next;
        }
    }
    internal sealed class TypeNode<T> : Node {
        public T m_data;

        public TypeNode(T data) : this(data, null) { }

        public TypeNode(T data, Node next)
            : base(next)
        {
            m_data = data;
        }
        public override string ToString()
        {
            return m_data.ToString() +
                ((m_next != null) ? m_next.ToString() : null);
        }
    }

程序入口:
 Node head = new TypeNode<Char>('.');
 head = new TypeNode<DateTime>(DateTime.Now, head);
 head = new TypeNode<String>("Today is ", head);
 Console.WriteLine(head.ToString());
程序输出:
Today is 2012-11-23 16:33:14.

 

posted @ 2012-11-26 10:27  Lordbaby  阅读(816)  评论(0编辑  收藏  举报