首页 > 代码库 > C# 里的泛型如何使用?

C# 里的泛型如何使用?

答:泛型是 C# 2.0 开始引入的一种更加灵活、规范的数据操作机制,看例子:

    class Student{}

    假设有学生对象需要存入集合,再提取出来

    ArrayList list = new ArrayList(); //1、实例化 list 集合对象

    Student s = new Student();        //2、实例化一个学生对象

    list.Add(s);                      //3、将学生存入集合

    Student tmp = (Student) list[0];  //4、将学生对象从集合中取出来

    传统的操作方式如上。

    如果,存入的是学生对象,而取出的时候错以为是老师对象,第 4 行代码可能写成:

    Teacher tmp = (Teacher) list[0];

    在编译时,系统不会发现这个问题,因为存入 list 的对象都会被装箱为 object ,取出的时候由 object 进行拆箱,系统没办法确定数据类型,所以,就算存入和取出的类型不一致,也不会提示错误。编译不出错,运行时肯定要出错了,因为学生对象强制转换为老师,是错误的。

    那如何尽早的进行类型规范和检查呢?使用泛型。

    List<Student> list = new List<Student>();           //1、实例化只能存放 Student 对象的集合

    Student s = new Student();        //2、实例化一个学生对象

    list.Add(s);                      //3、将学生存入集合

    Student tmp = list[0];            //4、将学生对象从集合中取出来

    注意代码的区别:

    第一行:我们没有再使用 ArrayList ,而是使用了 List 泛型集合

            语法:尖括号 < > 中的数据类型是在规范集合只能存入此类型数据。

    第四行:因为定义时有固定的操作类型(),所以,提取 list[0] 肯定是 Student 类型的对象,免去了数据类型转换的麻烦。

    那我们再使用 Teacher tmp = list[0]; 去进行错误类型的提取,程序将在编译时发现数据类型和泛型定义不一致的错误,使我们的程序更安全,更规范,同时,进出 list 集合的数据都有了类型,免去了传统集合进出数据时的装箱和拆箱的操作,提高了数据访问速度。

    泛型可以更规范的定义集合中存储的数据类型,其实可以以一种模板的方式来理解:

    List<Student> list = new List<Student>(); 相当于系统原有 List 集合类型是模板,我们通过模板创建了一种只能操作 Student 类型的集合。那模板的操作方式还有什么用途呢?

    现在我们调用 list.Sort() 方法,对集合当中的学生对象进行排序,因为 Student 类型不是系统内置的数据类型,所以排序操作肯定是错误的。那如果需要按照我们的要求进行排序,比如按年龄排序,又该怎么做呢?

    很多集合都需要有排序功能,所以系统有接口 IComparable ,来规范对象排序的操作。既然 IComparable 可以规范各种类型的排序,那就认为是一种模板,同时也就想到了泛型:

    class Student : IComparable<Student> //实现 泛型 比较接口

    {

        private int _age;

        public int Age { get ; set; }  //定义年龄属性

        public int CompareTo(Student other) //以泛型方式声明,所以操作对象也就是 Student

        {

            if(this.Age > other.Age)

                return 1;

            if(this.Age == other.Age)

                return 0;

            return -1;  //大于 等于 小于 对应返回 1 / 0 / -1

        }

    }

    这样操作 Student 类后,list.Sort() 功能也就可以通过调用 CompareTo 来对集合里的各个学生对象进行排序了。