泛型(Generic)接口

泛型接口例子:一个学生有一个独一无二的ID,但是每个学生的姓名不一定是唯一的。

    class Program
    {
        static void Main(string[] args)
        {
            Student<ulong> stu = new Student<ulong>();
            stu.ID = 2014031026;
            stu.Name = "Maomao";
        }
    }

    interface IUnique<Tid>
    {
        Tid ID { get; set; }
    }
    class Student<Tid>:IUnique<Tid>
    {
        public Tid ID { get; set; }
        public string Name { get; set; }
    }

如果这个类实现的是泛型接口,那么这个类也是泛型的,实现接口的时候必须把接口里全部的成员实现。

另一种情况,类实现的是特化之后的泛型接口,这样的类就不是泛型类了。

    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student();
            stu.ID = 2014031026;
            stu.Name = "Maomao";
        }
    }

    interface IUnique<Tid>
    {
        Tid ID { get; set; }
    }
    class Student : IUnique<ulong>
    {
        public ulong ID { get; set; }
        public string Name { get; set; }
    }

直接在类继承接口的时候就注入ulong类型,则类就不需要设置为泛型类了。

泛型List
在我们的.net种,几乎所有常用的数据结构都是泛型的,编程处理的数据中,大量的数据是存储在各种各样集合中的。
常用的集合有数组,列表,链表,字典等,这些数据结构以及它们的基接口,基类都是泛型的。

这些泛型的集合,数据结构以及它们的基接口,基类都集中在名称空间

using System.Collections.Generic;
    class Program
    {
        static void Main(string[] args)
        {
            IList<int> list = new List<int>();
            for (int i = 0; i < 100; i++)
            {
                list.Add(i);
            }
                foreach (var item in list)
                Console.WriteLine(item);
        }
    }

以上是一个带有一个类型参数的IList泛型接口和带有一个类型参数的List泛型类
C#中的List相当于Java中的ArrayList,在List泛型类的背后,维护着一个数组,我们可以不停的往这个数组里放东西,
当我们放的东西太多了超过我们数组的长度的时候 ,会再生成一个更长的数组,然后把我们输入的内容copy到这个更长的数组里。
我们知道数组的长度是不能够改变的,而我们List(Java中的ArrayList)的长度是可以改变的,有的书称之为动态数组。

我们去查看一下带有一个类型参数的List泛型类定义,
它有这么多接口:

ICollection接口代表它是一个集合,我们可以向其中添加移除元素,ICollection的定义为:

可以看到其中的各种方法内也有该类型参数。

不止一个参数类型的泛型接口和泛型类:
并不是所有泛型类都是只有一个参数类型,对于Ditionary这个字典类型(索引对应数据)就有两个参数类型。

TKey是索引,TValue是数据,组成这样的映射关系关系。

我们用int类型作为IDictionary的Key的类型,string类型作为IDictionary的Value类型,
然后IDictionary泛型接口被特化成了以int类型为key,string类型为value 。
我们利用之前学过的多态知识,接口类型的IDictionary变量可以引用一个Dictionary的实例
因为Dictionary泛型类实现了IDictionary接口(上图中所示),而且它的参数类型与IDictionary一致。
代码:

    class Program
    {
        static void Main(string[] args)
        {
            IDictionary<int, string> dict = new Dictionary<int, string>();
            dict[1] = "aaa";
            dict[2] = "bbb";
            Console.WriteLine($"Student #1 is {dict[1]}");
            Console.WriteLine("Student #2 is {dict[2]}");
        }
    }

输出的第二行我故意不写$,可以看到区别:

posted @ 2019-10-10 19:53  卯毛  阅读(347)  评论(0编辑  收藏  举报