前言

上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧。

一.理解泛型

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#中的泛型的更多相关文章

  1. 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...

  2. spring揭秘 读书笔记 二 BeanFactory的对象注册与依赖绑定

    本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,而且IoC Service Pr ...

  3. ES6读书笔记(二)

    前言 前段时间整理了ES6的读书笔记:<ES6读书笔记(一)>,现在为第二篇,本篇内容包括: 一.数组扩展 二.对象扩展 三.函数扩展 四.Set和Map数据结构 五.Reflect 本文 ...

  4. spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定

    本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Pr ...

  5. Mastering Web Application Development with AngularJS 读书笔记(二)

    第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...

  6. Servlet和JSP读书笔记(二)

    一. GenericServlet 1. 前面写的 Servlet和JSP学习笔记(一) 中的实例都是通过实现Servlet接口编写的,这样存在的问题就是:你必须实现Servlet中的所有方法,而不管 ...

  7. how tomcat works 读书笔记(二)----------一个简单的servlet容器

    app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...

  8. java读书笔记二

    这是我的一些读书笔记: 我研究了一下面向对象: 面向对象符合人类看待事物的一般规律,对象的方法的实现细节是包装的,只有对象方法的实现者了解细节 我觉得面向过程是由过程.步骤.函数组成,过程是核心,面向 ...

  9. 《JavaScript 高级程序设计》读书笔记二 使用JavaScript

    一   <script>元素 a.四个属性: async:立即异步加载外部脚本: defer:延迟到文档完全被解析再加载外部脚本: src:外部脚本路径: type:脚本语言的内容类型: ...

随机推荐

  1. hdu6075 2019CCPC网络选拔赛1004 path

    题意:给定一个带权有向图,有q组询问,每次询问在有向图的所有路径中,第k小的路径权值 解题思路:因为k最大只有5e4,考虑暴力搜索出前maxk小的路径并用数组记录权值,然后就可以O(1)查询. 具体实 ...

  2. vue3剖析:响应式原理——effect

    响应式原理 源码目录:https://github.com/vuejs/vue-next/tree/master/packages/reactivity 模块 ref: reactive: compu ...

  3. Hexo博客迁移

    Hexo用户指南 - 博客迁移 GitHub+Hexo搭建博客的过程比较平滑,但是它的配置却非常耗时,一旦电脑出现问题或者需要在另外一台电脑上写博客,那么Hexo博客的迁移非常就让人头疼.下面参考其他 ...

  4. console.info(sum(1, 2, 3, 4)(5)(6));

     function add() {    // 第一次执行时,定义一个数组专门用来存储所有的参数    var _args = [].slice.call(arguments); // 在内部声明一个 ...

  5. 如何用canvas拍出 jDer's工作照

    背景 在京东,就职满五年的老员工被称作"大佬",如果满了十年,那就要被称之为"超级大佬"了. 从 2016 年 5 月 19 日开始,每一年的这一天都被定为京东 ...

  6. 使用阿里云OSS的服务端签名后直传功能

    网站一般都会有上传功能,而对象存储服务oss是一个很好的选择.可以快速的搭建起自己的上传文件功能. 该文章以使用阿里云的OSS功能为例,记录如何在客户端使用阿里云的对象存储服务. 服务端签名后直传 背 ...

  7. 如何借助 IDEA 数据库管理工具可视化使用 TDengine?

    什么是IDEA Database管理工具? 这里首先介绍下IDEA,IDEA全称IntelliJ IDEA,是Java语言开发的集成环境,IntelliJ在业界被公认为最好的Java开发工具之一. I ...

  8. 学习 | css3实现进度条加载

    进度条加载是页面加载时的一种交互效果,这样做的目的是提高用户体验. 进度条的的实现分为3大部分:1.页面布局,2.进度条动效,3.何时进度条增加. 文件目录 加载文件顺序 <link rel=& ...

  9. Windows提示80被占用

    情景:使用cmd启动某一服务的时候报错[emerg] 7220#6900: bind() to 0.0.0.0:80 failed (10013: An attempt was made to acc ...

  10. Vue 登录/登出以及JWT认证

    1. 后端代码概览 server/router/index.js 请求 router.get('/getUserInfo', function (req, res, next) { // 登录请求 r ...