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

这样下去如果有更多的东西需要套盒子,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. 在Feign中添加自定义配置

    首先先创建一个FeignConfig类,代码如下: package com.xing.config; import org.springframework.context.annotation.Bea ...

  2. poj 3294 后缀数组+二分

    题目大意: 给定n个字符串,求出现在不小于k个字符串中的最长子串 基本思路: 二分长度,统计个数,一般套路,就是这个跟说好的不一样啊,我非得开2倍才不re,真他妈不爽,先二分找出长度,然后根据长度输出 ...

  3. vue 使用Animate.css库

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. PHP构建一句话木马

    构建一句话木马,密码为simple: url/search.php?searchtype=5&tid=&area=eval($_POST[simple]) 之后使用菜刀进行链接,密码为 ...

  5. css 一行内显示 超出自动隐藏

    一般的文字截断(适用于内联与块): Example Source Code [www.mb5u.com].text-overflow {display:block;/*内联对象需加*/width:31 ...

  6. 【TCP/IP】TCP的三次握手和四次挥手

    传输控制协议(TCP)是一种面向连接的协议,网络程序使用这个协议的时候,网络可以保证客户端和服务端的连接是可靠的,安全的. 如果 A机向 B机发送“hello”,在物理网线上传输的数据不仅仅是“hel ...

  7. C语言变长参数实现

    #include<stdio.h> #include<string.h> #include<stdarg.h> /***编写可变长参数列表的函数案例*/ /* vo ...

  8. thinkphp5选择redis库,让数据存入不同的redis库

    thinkphp5选择redis库,让数据存入不同的redis库 在登录的时候把个人信息存入redis,选择redis库1号库, db1 读取redis里面的个人信息

  9. TI低功耗蓝牙(BLE)介绍【转】

    转自:http://blog.csdn.net/ooakk/article/details/7302425 TI低功耗蓝牙(BLE)介绍 本文档翻译和修改自参考资料:CC2540Bluetooth L ...

  10. Linux分页机制

    地址长度 在Linux下,unsigned long可以与地址的长度保持一致,即32位系统下unsigned long为32位,而64位系统下为64位长. 虚拟地址的分解 如图所示,通过XXX_SHI ...