泛型(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)类的使用原因和使用方式的更多相关文章
- Java基础之Comparable接口, Collections类,Iterator接口,泛型(Generic)
一.Comparable接口, Collections类 List的常用算法: sort(List); 排序,如果需要对自定义的类进行排序, 那就必须要让其实现Comparable接口, 实现比较两个 ...
- C#泛型(Generic)
一.什么是泛型 泛型(Generic)是C#语言2.0.通用语言运行时(CLR)2.0..NET Framework2.0推出来的新特性. 泛型为.NET框架引入类型参数(Type Parameter ...
- Boost源码剖析之:泛型指针类any
C++是强类型语言,所有强类型语言对型别的要求都是苛刻的,型别一有不合编译器就会抱怨说不能将某某型别转换为某某型别,当然如果在型别之间提供了转换操作符或是标准所允许的一定程度的隐式转换(如经过非exp ...
- Java - 泛型 ( Generic )
Java - 泛型 ( Generic ) > 泛型的特点 > 解决元素存储的安全性问题 > 解决获取数据元素时,需要类型强转的问题 ...
- Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口
Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器 ...
- RestTemplate将响应数据转换为具有泛型的类对象
前言: 重要,RestTemplate在SpringBoot项目里即便通过HttpMessageConverters添加了Fastjson且优先级比jackson要高也不会在RestTemplate里 ...
- JavaWeb_泛型(Generic)
JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免的就会引发程序的一些安全性问题.例如: ArrayList list = new ArrayList ...
- Dephi泛型generic的应用
Dephi泛型generic的应用 泛型在C++, C#中已有广泛应用,Delphi自2009版本也引入泛型,典型的应用如TList,TDictionary.如果你熟悉C#,其用法十分类似. 比如 ...
- 泛型(Generic)
当集合中存储的对象类型不同时,那么会导致程序在运行的时候的转型异常 import java.util.ArrayList; import java.util.Iterator; public clas ...
随机推荐
- Linux入门命令
####常用的目录 /主目录 ① /root:存放启动Linux时启动的核心文件,包括一些连接文件以及镜像 ② /bin:binary的缩写,存放经常使用的命令 ③ /dev:Device(设备)的缩 ...
- 记录一下list转map
Map<String,String> mapListStream = list.stream().collect(Collectors.toMap(key,value)):key对应key ...
- 【Muduo库】【base】基本类
一.Timestamp类 1.类图如下: 2. 知识点 (1) 这个类继承了 muduo::copyable, 以及 boost::less_than_comparable. (2) ...
- 循环神经网络(Recurrent Neural Network)
传统的神经网络模型,隐藏层的节点之间是无连接的,如下图所示. 而循环神经网络隐藏层的节点之间有连接,主要用于对序列数据进行分类.预测等处理.有连接意味着需要接受信息,这种网络通常用来对序列数据进行处理 ...
- promise、async、await、settimeout异步原理与执行顺序
一道经典的前端笔试题,你能一眼写出他们的执行结果吗? async function async1() { console.log("async1 start"); await as ...
- mobx中使用class语法或decorator修饰器时报错
之前课程中老师用的babel的版本比较低,我在学习时安装的babel版本较高,因此每当使用class语法或decorator修饰器时都会出现一些报错的情况! ❌ ERROR in ./src/inde ...
- Dart编程实例 - 类型测试操作符 is!
Dart编程实例 - 类型测试操作符 is! void main() { double n = 2.20; var num = n is! int; print(num); } 本文转自:http:/ ...
- JSTL标签的用法详解
在JSP中写Java代码是一件很恶心的事情,代码量少的话还可以,要是多的话,就蛋疼了,整个页面都是<% %>所以EL表达式和JSTL就应运而生了,这里我们注重讲解一下JSTL标签的使用: ...
- Shell基础(五):sed基本用法、使用sed修改系统配置、sed多行文本处理、sed综合脚本应用
一.sed基本用法 目标: 本案例要求熟悉sed命令的p.d.s等常见操作,并结合正则表达式,完成以下任务: 1> 删除文件中每行的第二个.最后一个字符 2> 将文件中每行的第一个. ...
- Linux环境下安装PHP的mbstring模块
cd /home/local/php-5.6.25/ext/mbstring/usr/local/php/bin/phpize./configure --with-php-config=/usr/lo ...