【记】《.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:脚本语言的内容类型: ...
随机推荐
- 简介&目录
欢迎来到 MK 的博客鸭~ 这里会被我用来发一些OI算法.数据结构的学习笔记,各种游记和其他的一些内容,希望大家多多关照! ε≡٩(๑>₃<)۶ 然后目录就也放这里⑧:
- 你不得不知的Java基础知识
本篇博客主要记录Java中面向对象的概念和Java语法的基础知识. 面向对象 什么是面向对象 面向对象是一种优秀的软件设计思想,是相对于面向过程.面向切面等设计思想的一种软件设计理念.它的核心思想是运 ...
- 11_Python的69个内置函数详解
1.内置函数分类 思维导图: https://www.processon.com/view/link/5dcabc48e4b0bd68d813b24f 2.基础数据类型-和数字相关的函数(14) 数据 ...
- 剑指 Offer 55 - I. 二叉树的深度
题目描述 输入一棵二叉树的根节点,求该树的深度.从根节点到叶节点依次经过的节点(含根.叶节点)形成树的一条路径,最长路径的长度为树的深度. 例如: 给定二叉树 [3,9,20,null,null,15 ...
- 用Python实现十大经典排序算法-插入、选择、快速、冒泡、归并等
本文来用图文的方式详细讲解了Python十大经典排序算法 —— 插入排序.选择排序.快速排序.冒泡排序.归并排序.希尔排序.插入排序.桶排序.基数排序.计数排序算法,想要学习的你们,继续阅读下去吧,如 ...
- 浅谈DOM事件的优化
在 JavaScript 程序的开发中,经常会用到一些频繁触发的 DOM 事件,如 mousemove.resize,还有不是那么常用的鼠标滚轮事件:mousewheel (在 Firefox 中,滚 ...
- [03] C# Alloc Free编程
C# Alloc Free编程 首先Alloc Free这个词是我自创的, 来源于Lock Free. Lock Free是说通过原子操作来避免锁的使用, 从而来提高并行程序的性能; 与Lock Fr ...
- 微信小程序爬坑记
1.this.setData修改数组里的值1).data: { hide:[true,true] },this.setData({ 'hide[0]': false});2).var str = &q ...
- 秒懂JVM的三大参数类型,就靠这十个小实验了
秒懂JVM的三大参数类型,就靠这十个小实验了 你好,我是悟空哥,「7年项目开发经验,全栈工程师,开发组长,超喜欢图解编程底层原理」.手写了2个小程序,Java刷题小程序,PMP刷题小程序,已发布到公众 ...
- CTF-BugKu-WEB-35-41
2020.09.19 go on,今天务必搞定web 经验教训 能运行php标签的扩展名有php4,phtml,phtm,phps,php5等,可以在php被过滤的时候尝试: html请求头中,对内容 ...