【记】《.net之美》之读书笔记(二) C#中的泛型
前言
上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧。
一.理解泛型
1.为什么要使用泛型?-----通过使用泛型,可以极大地提高代码的重用度,同时还可以获得强类型的支持,提升了应用程序的性能,避免了隐式的装箱、拆箱,以及运行时的类型转换错误。
2.为什么要有泛型? -----以简单的数组排序为例,第一次我们可能会要求对int型数组进行排序,然后我们很快的写出了答案,
第二次,又要求我们对byte[]数组进行排序,这时候我们可能会思考下,是不是要优化我们的设计思想,但是还不至于修改,我们还是快速的将int[]数组的排序代码进行了复制,将方法签名改为byte[].
第三次,又要求我们对char[]数组进行排序,这个时候我们就不得不停下来思考了,以上两种需求,除了方法签名不一样以为,其他的都一模一样。所以我们引进了泛型的概念,将int[]、byte[]、char[]使用T[]来表示,T代表type,指代任何类型。所以我们又得到了泛型类的概念。
public class SortHelper<T> {
public void BubbleSort(T[] array){
// 方法实现体
}
}
这样,当我们需要对int[]进行排序时,我们可以这样声明:
SortHelper<int> sorter = new SortHelper<int>();
int[] array = { 8, 1, 4, 7, 3 };
sorter.BubbleSort(array);
当我们需要对char[]进行排序时,我们就能这样声明:
SortHelper<char> sorter = new SortHelper<char>();
char [] array = { 8, 1, 4, 7, 3 };
sorter.BubbleSort(array);
再也不用重复的对代码进行复制,然后修改方法签名了。
结论:通过使用泛型,极大的减少了重复代码,使程序更加清爽。泛型类可以让我们在需要时传入任何类型,在.net中,我们称作类型参数。
3.类型参数约束
我们定义了一个Book类,对它实现排序,该怎么实现呢?假设该类包含两个字段,一个int类型的单价price,一个string类型的title标题。
Book[] bookArray = new Book[2];
Book book1 = new Book(30, "HTML5解析");
Book book2 = new Book(21, "JavaScript实战");
bookArray[0] = book1;
bookArray[1] = book2;
SortHelper<Book> sorter = new SortHelper<Book>();
sorter.BubbleSort(bookArray);
foreach (Book b in bookArray) {
Console.WriteLine("Price:{0}", b.Price);
Console.WriteLine("Title:{0}\n", b.Title);
}
那么到底该怎么进行比较大小呢? 是以价格为准呢,还是以书名的字母顺序呢?都不好说,所以这个时候就需要定义一个比较规则了,那么在.net中,实现比较的基本方法是实现IComparable接口。此接口有泛型和非泛型两个。
public class Book :IComparable {
// CODE:上面的实现略
public int CompareTo(object obj) {
Book book2 = (Book)obj;
returnthis.Price.CompareTo(book2.Price);
}
}
这里我们以price为准来进行排序,可以看到CompareTo()方法参数接受了一个object类型的参数,我们却违背了Liskov替换原则。原则要求方法内部不应该对方法所接受的参数进行向下的强制转换。我们都知道,在C#中,object是一切类型的基类。book类继承自Object类,所以我们在将object转换为book进行价格比较时,就称作向下的强制转换.
泛型类,所接受的T类型参数必须能够进行比较--即实现IComparable接口,所以我们可以这样定义:
public class SortHelper<T> where T:IComparable {
// CODE:实现略
}
4.泛型方法
既然有了泛型类,我们就引入了泛型方法的概念,泛型方法的引入主要是为了解决,我们在声明泛型类时,避免因为调用某一个方法不得不将类型参数T传给某个类,使得那些不需要调用该方法的情况下,创建一个类实例也需要传递类型参数的情况。
如下:SpeedSort()就是一个泛型方法
public class SortHelper
{
public void SpeedSort<T>(T[] Array) where T:IComparable
{
}
}
二.泛型和集合类型
1.避免隐式的装箱拆箱
典型的非泛型集合ArrayList,它包容了任何类型, 所以它接受的参数为所有类型的基类Object, 当我们需要获取到一个int[],需要循环遍历ArrayList,并将它一一添加到我们所声明的数组集合中去,由于object是一个引用类型,而int是一个值类型,这样在得到这么一个包含int类型的ArrayList数组时,我们就需要不断的进行装箱、拆箱的操作,这对.net来说是相对耗时的。
通过使用泛型,由于集合中的元素类型在编译时就已确定,避免了装箱和拆箱的操作,很显著的提高集合类型的性能。 在.NET中,与ArrayList作用等同的泛型类型是 List.
2.编译时的类型安全
由于使用泛型,集合中的元素在编译时就已确定,所以当我们想将一个int类型的数值转换为string时,编译器会直接告诉我们编译错误,这种在编译时就检查出的错误,叫做编译时错误,与之相对的,就是我们的运行时错误,即当使用ArrayList时,因为它所接受的参数是object基类,编译器视为将一个int类型的数值转换为string时是正常的,只有运行时才检查出错误。
三.小结
本章学习了为什么需要泛型(避免重复代码)以及如何使用类型参数约束和泛型方法,并且比较了泛型集合List和非泛型集合ArrayList的对比,熟悉并了解了泛型集合的优势和应用。
很开心,又跟随作者学习了第二章泛型的概念,上一篇读书笔记中,很多小伙伴给我留言了,说了很多鼓励的话,很感谢,能和大家一起进步学习,其中有一位小伙伴提到的方法我觉得很棒,就是大量阅读开源源码,确实,我在园子里看到很多对底层原理理解很透彻的大佬们,每每讲解一个知识点时,总是会教我们去跟踪源码,即理解它的底层实现逻辑是啥,这样更能加深我们对知识点的理解和巩固。
我也是在学习中,希望自己在今后的学习和工作中,能掌握这种技巧,帮助自己更好的理解并熟悉它的原理。
【记】《.net之美》之读书笔记(二) C#中的泛型的更多相关文章
- 《你必须知道的.NET》读书笔记二:小OO有大原则
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...
- spring揭秘 读书笔记 二 BeanFactory的对象注册与依赖绑定
本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,而且IoC Service Pr ...
- ES6读书笔记(二)
前言 前段时间整理了ES6的读书笔记:<ES6读书笔记(一)>,现在为第二篇,本篇内容包括: 一.数组扩展 二.对象扩展 三.函数扩展 四.Set和Map数据结构 五.Reflect 本文 ...
- spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定
本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Pr ...
- Mastering Web Application Development with AngularJS 读书笔记(二)
第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...
- Servlet和JSP读书笔记(二)
一. GenericServlet 1. 前面写的 Servlet和JSP学习笔记(一) 中的实例都是通过实现Servlet接口编写的,这样存在的问题就是:你必须实现Servlet中的所有方法,而不管 ...
- how tomcat works 读书笔记(二)----------一个简单的servlet容器
app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...
- java读书笔记二
这是我的一些读书笔记: 我研究了一下面向对象: 面向对象符合人类看待事物的一般规律,对象的方法的实现细节是包装的,只有对象方法的实现者了解细节 我觉得面向过程是由过程.步骤.函数组成,过程是核心,面向 ...
- 《JavaScript 高级程序设计》读书笔记二 使用JavaScript
一 <script>元素 a.四个属性: async:立即异步加载外部脚本: defer:延迟到文档完全被解析再加载外部脚本: src:外部脚本路径: type:脚本语言的内容类型: ...
随机推荐
- Stone(思维)
链接:https://ac.nowcoder.com/acm/contest/893/D来源:牛客网 题目描述 有n堆石子排成一排,第i堆石子有aiai个石子. 每次,你可以选择任意相邻的两堆石子进行 ...
- Codeforces1312E Array Shrinking 区间DP
题意 给你一个数组\(a\),只要满足\(a_i=a_{i+1}\)就可以将这两个元素合并成一个值为\(a_i+1\)的元素,问数组最小长度. 解题思路 记得之前某场的F和这题差不多,当时好像是相邻且 ...
- Activiti7 获取资源信息及其查询流程历史信息
获取资源信息 /** * 获取资源信息 * * @throws IOException */ @Test public void getProcessResources() throws IOExce ...
- vue安装pubsub-js 库的命令
1.查看pubsub-js 库是否已经存在该库命令: npm info pubsub-js 2.若不存在,则先安装pubsub-js 库,命令如下: npm install --save pubsub ...
- 转载:SQL语句执行顺序
转载地址:https://database.51cto.com/art/202001/609727.htm
- Spring JPA 查询创建
Spring JPA 查询创建 这是JPA内容的核心部分,可以收藏用作参阅文档. 1. 查询转化和关键字 例:一个JPA查询的转化 public interface UserRepository ex ...
- leetcode刷题-78子集
题目 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3]输出:[ [3], [1], [2] ...
- python:列表生成式和三元表达式、匿名函数
一.列表生成式 1.列表生成式就是python内置的一种用来生成list的生成式. 比如下面这个例子: l=[] for i in range(10) list.append(i) 生成一个列表要用循 ...
- db2官方文档
开局贴链接.这个东西是真坑,下载竟然需要账号... (我就做一下记录,别喷我)
- linux下redis安装部署
1.获取redis资源 进官网下载https://redis.io/download最新版本后将文件移到linux环境中 或者直接wget http://download.redis.io/relea ...