我们每个苹果都套个盒子,给每本书都套个盒子,但是苹果盒子和书盒子是不同的,

这样下去如果有更多的东西需要套盒子,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)类的使用原因和使用方式的更多相关文章

  1. Java基础之Comparable接口, Collections类,Iterator接口,泛型(Generic)

    一.Comparable接口, Collections类 List的常用算法: sort(List); 排序,如果需要对自定义的类进行排序, 那就必须要让其实现Comparable接口, 实现比较两个 ...

  2. C#泛型(Generic)

    一.什么是泛型 泛型(Generic)是C#语言2.0.通用语言运行时(CLR)2.0..NET Framework2.0推出来的新特性. 泛型为.NET框架引入类型参数(Type Parameter ...

  3. Boost源码剖析之:泛型指针类any

    C++是强类型语言,所有强类型语言对型别的要求都是苛刻的,型别一有不合编译器就会抱怨说不能将某某型别转换为某某型别,当然如果在型别之间提供了转换操作符或是标准所允许的一定程度的隐式转换(如经过非exp ...

  4. Java - 泛型 ( Generic )

    Java - 泛型 ( Generic )     > 泛型的特点         > 解决元素存储的安全性问题         > 解决获取数据元素时,需要类型强转的问题     ...

  5. Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口

    Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器 ...

  6. RestTemplate将响应数据转换为具有泛型的类对象

    前言: 重要,RestTemplate在SpringBoot项目里即便通过HttpMessageConverters添加了Fastjson且优先级比jackson要高也不会在RestTemplate里 ...

  7. JavaWeb_泛型(Generic)

    JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免的就会引发程序的一些安全性问题.例如: ArrayList list = new ArrayList ...

  8. Dephi泛型generic的应用

    Dephi泛型generic的应用   泛型在C++, C#中已有广泛应用,Delphi自2009版本也引入泛型,典型的应用如TList,TDictionary.如果你熟悉C#,其用法十分类似. 比如 ...

  9. 泛型(Generic)

    当集合中存储的对象类型不同时,那么会导致程序在运行的时候的转型异常 import java.util.ArrayList; import java.util.Iterator; public clas ...

随机推荐

  1. Android中XML的命名空间、自定义属性

    命名空间(namespace) XML 命名空间提供避免元素命名冲突的方法. 举个例子,A学校有名学生叫做林小明,B学校也有名学生叫林小明,那我们如何识别这两名拥有相同名字的同学呢?这时候命名空间就派 ...

  2. netstat 指令

    netstat 指令将所有的网络端口监听情况进行罗列 语法  netstat -tuln 几个常见的服务端口 例  通过grep 查看端口来获得上面的服务是否开启,并给予提示 1 #!/bin/bas ...

  3. 三重循环之break

    while(1) { while(1) { while(1) { break; } } } //逻辑堪比绝技啊 脑洞开之注册表循环遍历方法

  4. mybatis xml中大于号小于号的代替

    第一种写法(1): 原符号 < <= > >= & ' "替换符号 < <= > >= & &apos; " ...

  5. lct 模版题 bzoj 2002 2049

    很早就有人给我推荐的模版题,然后我最近才刷的(' '    ) 昨天的tree 不知道比他们高到哪里去了,我和他谈笑风生啊! bzoj 2002 弹飞绵羊 重点:这道题的cut和link 由于这道题链 ...

  6. Vue 事件相关实例方法---on/emit/off/once

    一.初始位置 平常项目中写逻辑,避免不了注册/触发各种事件 今天来研究下 Vue 中,我们平常用到的关于 on/emit/off/once 的实现原理 关于事件的方法,是在 Vue 项目下面文件中的 ...

  7. luoguP2709 小B的询问 [莫队]

    题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...

  8. PHP学习(MVC架构与面向对象)

    想好好的学一下php中的一些面向对象的知识,以前只是为了打CTF随意的学了一下,但是为了以后的代码审计(准备PHP这边把thinkphp这个框架好好的学一下). PHP面向对象的基本知识 类与对象 类 ...

  9. VMware Network Adapter VMnet1/8详解

    转自:https://www.cnblogs.com/systemnet123/articles/2640883.html VMWare提供了三种工作模式,它们是bridged(桥接模式).NAT(网 ...

  10. java8的正确使用姿势

    ackage com.expgiga.Java8; import java.util.ArrayList; import java.util.Arrays; import java.util.List ...