日期:2014-05-17  浏览次数:20930 次

关于泛型
下边的代码是我查msdn的帮助,里边代码大意知道,但是有些表达方式不懂

1.public class GenericList<T> 表示定义一个类吗? 因为以前定义类直接给一个名称, 这个还加了一个<T>,这种表达方式有些费解。

2.public IEnumerator<T> GetEnumerator() ,返回的是一个Node 类型,可是根据IEnumerator<T> 字面是一个接口,我的理解应该是public Node GetEnumerator() 

请解释下

C# code


在 AddHead 方法中作为方法参数的类型。

在 Node 嵌套类中作为公共方法 GetNext 和 Data 属性的返回类型。

在嵌套类中作为私有成员数据的类型。

注意,T 可用于 Node 嵌套类。如果使用具体类型实例化 GenericList<T>(例如,作为 GenericList<int>),则所有的 T 都将被替换为 int。

// type parameter T in angle brackets
public class GenericList<T> 
{
    // The nested class is also generic on T
    private class Node
    {
        // T used in non-generic constructor
        public Node(T t)
        {
            next = null;
            data = t;
        }

        private Node next;
        public Node Next
        {
            get { return next; }
            set { next = value; }
        }
        
        // T as private member data type
        private T data;

        // T as return type of property
        public T Data  
        {
            get { return data; }
            set { data = value; }
        }
    }

    private Node head;
    
    // constructor
    public GenericList() 
    {
        head = null;
    }

    // T as method parameter type:
    public void AddHead(T t) 
    {
        Node n = new Node(t);
        n.Next = head;
        head = n;
    }

    public IEnumerator<T> GetEnumerator()
    {
        Node current = head;

        while (current != null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }
}





------解决方案--------------------
1.public class GenericList<T> 表示定义一个类吗?

准确的说,GenericList不是一个类,而是一个能够派生出一组类的东西,应该叫“泛型类”吧,所谓的“泛型类”是一个“带参数”的类,而T就是它的参数,

其实GenericList不是一个类,但GenericList<int>就是一个类,int相当于是实参,把T给替换掉了,在GenericList内部所有出现T的地方,都替换为int,就是GenericList<int>了,你会发现,GenericList<int>确实是一个类,它有方法,属性,而且方法属性都是确定的可以编译运行的,因为它已经把T替换为int,完全确定了,

可以看得出,虽然GenericList不是一个类,但它可以“实例化”为非常多个类,比如GenericList<int>、GenericList<double>、GenericList<string>等,显而易见的好处是,你用T来写的GenericList泛型,只需要把T替换为int,double,string,就可以得多多个类,而且你无需再次写方法里的代码,

定义一个泛型,可以让你轻松获得多个类,

从另一个角度来说,如果你不用泛型,而是实现GenericList<int>、GenericList<double>、GenericList<string>等类,你会发现,除了元素的类型不同之外,这些类的代码基本完全相同,你在写重复的代码,为何把使用一个参数T来代替int,double,string等类型,这样就可以省掉重复实现,

------解决方案--------------------
2.public IEnumerator<T> GetEnumerator() ,返回的是一个Node 类型,

你理解错了,返回的不是Node类型,而是实现了IEnumerator<T>接口的一个类实例的引用,这个类实例其实是yield return current.Data这句话创建的,或者说是c#编译器根据yield语句帮你生成了一个类,这个类从IEnumerator<T>接口中继承,

一般来说,使用迭代器你无需自己从IEnumerator<T>接口派生一个类,只需要用yield关键字,c#编译器会帮你生成这个类,并且继承IEnumerator<T>接口的方法,甚至c#编译器会帮你实现这些方法,无需你写代码实现,

这个方法返回的IEnumerator<T>接口引用完全和Node泛型类无关,它是编译器生成的,
------解决方案--------------------
简单的说T就是指任意类型!
------解决方案--------------------
<T>,这里的T,理解成Type,一种类型。
一般来说这个乏型就是他处理的<T>数据时,这个数据类型可变,可以是class a,也可以class b,有些时候很方便。
------解决方案--------------------
你连为什么用都不知道,干嘛就看怎么去写了呢?等你实际用到了再看是怎么写的也不迟,这个必须自己在编码过程中体会,用到了自然就知道,用不到你也没必要去关心。
------解决方案--------------------
探讨

你连为什么用都不知道,干嘛就看怎么去写了呢?等你实际用到了再看是怎么写的也不迟,这个必须自己在编码过程中体会,用到了自然就知道,用不到你也没必要去关心。

------解决方案--------------------
List<T> 不算是一个具体的类,只能算是一个类的模板,具体制定了 T 类型之后才能确定为一个具体的类,比如:List<int> 和 List<string>