泛型(Generic)类的使用原因和使用方式

Posted maomaodesu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了泛型(Generic)类的使用原因和使用方式相关的知识,希望对你有一定的参考价值。

我们每个苹果都套个盒子,给每本书都套个盒子,但是苹果盒子和书盒子是不同的,
这样下去如果有更多的东西需要套盒子,1000种产品有1000种相应的盒子,造成类型极度膨胀非常难以维护。

    class Program
    {
        static void Main(string[] args)
        {
            Apple apple = new Apple() { Color = "Red" };
            AppleBox abox = new AppleBox() { Cargo = apple };
            Console.WriteLine(abox.Cargo.Color);

            Book book = new Book() {Name = "New Book"};
            BookBox bbox = new BookBox() { Cargo = book };
            Console.WriteLine(bbox.Cargo.Name);
        }
    }
    class Apple
    {
        public string Color { get; set; }
    }
    class Book
    {
        public string Name { get; set; }
    }
    class AppleBox
    {
        public Apple Cargo { get; set; }
    }

    class BookBox
    {
        public Book Cargo { get; set; }
    }

我们只准备一种盒子,让这种盒子有不同属性可以装任何东西。
如果有1000种东西需要1000种盒子,在Box类种有1000个对应属性,每次只有1个有用,999个没有用。
另外如果又来了新的物品,则要修改Box类,增加新的属性。忘记增删属性会导致bug和代码不完善,这叫做成员膨胀。

    class Program
    {
        static void Main(string[] args)
        {
            Apple apple = new Apple() { Color = "Red" };
            Book book = new Book() { Name = "New Book" };
            Box box1 = new Box() { Apple = apple };//用了Apple属性,没用Book属性
            Box box2 = new Box() { Book = book };//反之
        }
    }
    class Apple
    {
        public string Color { get; set; }
    }
    class Book
    {
        public string Name { get; set; }
    }
    class Box
    {
        public Apple Apple { get; set; }
        public Book Book { get; set; }
    }

还有一种解决方案,那就是在声明Box的属性的时候 不要指明具体类型,用Object类型就可以了。

   class Program
   {
       static void Main(string[] args)
       {
           Apple apple = new Apple() { Color = "Red" };
           Book book = new Book() { Name = "New Book" };
           Box box1 = new Box() { Cargo = apple };
           Box box2 = new Box() { Cargo = book };
       }
  
}

Apple和Box类略

    class Box
    {
        public  object Cargo { get; set; }
    }

但是我们看不到Color属性了
技术图片
如果想只当盒子里是Apple的时候才看到Color属性,那么就强制类型转换(略)或者使用as操作符

            Console.WriteLine((box1.Cargo as Apple)?.Color);

其中,box1里是苹果,box2里是书,这里(box1.Cargo as Apple)表示对象,“?”表示如果是Apple则.Color,否则不执行。

但是依然很麻烦呀。

因此我们引入泛型!

    class Box<类型参数>
    {
        public  类型参数 Cargo { get; set; }
    }

所谓类型参数就是一个标识符,是一个泛化的类型
因此我们给类型参数起名TCargo,T表示泛型
因此修改Box类为:

    class Box<TCargo>
    {
        public  TCargo Cargo { get; set; }
    }

Program类变为

    class Program
    {
        static void Main(string[] args)
        {
            Apple apple = new Apple() { Color = "Red" };
            Book book = new Book() { Name = "New Book" };
            Box<Apple> box1 = new Box<Apple>() { Cargo = apple };
            Box<Book> box2 = new Box<Book>() { Cargo = book };
            Console.WriteLine(box1.Cargo.Color);
            Console.WriteLine(box2.Cargo.Name);
        }
    }

我们发现这样是可以根据装不同东西的盒子,点出不同的属性的,完美解决了问题。
技术图片

以上是关于泛型(Generic)类的使用原因和使用方式的主要内容,如果未能解决你的问题,请参考以下文章

泛型(Generic)

Java泛型Generic - Thinking in Java读书笔记

java-List

泛型 Generic 类型擦除引起的问题及解决方法

选择Typescript的原因:支持定义执行时的泛型参数

详解 Java 泛型(Generic)机制