《C#高级编程》读书笔记(三):关于泛型
2016-06-25 10:26
309 查看
一开始我觉着这本书太厚了,直到看到泛型这一章,发现这本书真不够,毕竟要把一个复杂的概念讲透,没一定的篇幅是不可能的。
泛型这个概念困扰我很久了,所以我把这章翻来覆去看了好几遍,又去网上找了一些文章,算是搞明白了。
先看看泛型的概念:“通过参数化类型来实现在同一份代码上操作多种数据类型。利用“参数化类型”将类型抽象化,从而实现灵活的复用”。所以,有了泛型,就可以创建独立于被包含类型的类和方法了。不必给不同的类型编写功能相同的许多方法或类,只创建一个方法或类即可。
废话少说,来看代码:
1,不用泛型的后果
我们创建一个方法对int数组进行排序,算法是冒泡:
测试:
输出为:0,1,2,2,3,4,5,5,8
如果数组是Byte类型的呢,简单,直接复制方法,改改签名就完事了
如果再引入其他数据类型的方法呢,那这个类就没法看了,长不说,维护起来也很麻烦,如果我想把冒泡改为快排,那每个方法都要改,那怎么办呢,这个时候就可以引入泛型。
2,使用泛型
简而言之,用“T”来代替具体的类型
这里我们需要把SortHelper定义类泛型类:
测试一下:
输出:
0,1,2,2,3,4,5,5,8
0,1,2,2,3,4,5,5,8
3,为什么不用object
1)泛型不需要装箱和拆箱,性能好
2)泛型是类型安全的
3)泛型可以二进制代码重用
4,泛型约束:约束声明了泛型要求的类型参数的特征。
为了声明一个约束,需要使用where关键字,后跟一对”参数:要求”.其中,”参数”必须是泛型类型中定义的一个参数,而”要求”用于限制类型从
中”派生”的类或接口,或者限制必须存在一个默认构造器,或者限制使用一个引用/值类型约束.
约束的例子可以看这里:http://www.cnblogs.com/smiler/p/3163312.html
5,协变和逆变
示例代码从这里抄的:http://www.cnblogs.com/keiling/p/3672346.html
泛型这个概念困扰我很久了,所以我把这章翻来覆去看了好几遍,又去网上找了一些文章,算是搞明白了。
先看看泛型的概念:“通过参数化类型来实现在同一份代码上操作多种数据类型。利用“参数化类型”将类型抽象化,从而实现灵活的复用”。所以,有了泛型,就可以创建独立于被包含类型的类和方法了。不必给不同的类型编写功能相同的许多方法或类,只创建一个方法或类即可。
废话少说,来看代码:
1,不用泛型的后果
我们创建一个方法对int数组进行排序,算法是冒泡:
public class SortHelper { public void BubbleSort(int[] arr) { int length = arr.Length; for (int i = 0; i < length-1; i++) { for (int j = 0; j < length-1-i; j++) { if (arr[j]>arr[j+1]) { int temp=arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
测试:
static void Main(string[] args) { SortHelper sorter = new SortHelper(); int[] a = { 4,5,1,3,2,8,5,0,2}; sorter.BubbleSort(a); //输出省略 }
输出为:0,1,2,2,3,4,5,5,8
如果数组是Byte类型的呢,简单,直接复制方法,改改签名就完事了
public class SortHelper { public void BubbleSort(byte[] arr) { int length = arr.Length; for (int i = 0; i < length-1; i++) { for (int j = 0; j < length-1-i; j++) { if (arr[j]>arr[j+1]) { byte temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
如果再引入其他数据类型的方法呢,那这个类就没法看了,长不说,维护起来也很麻烦,如果我想把冒泡改为快排,那每个方法都要改,那怎么办呢,这个时候就可以引入泛型。
2,使用泛型
简而言之,用“T”来代替具体的类型
public class SortHelper { public void BubbleSort(T[] arr) { int length = arr.Length; for (int i = 0; i < length-1; i++) { for (int j = 0; j < length-1-i; j++) { if (arr[j]>arr[j+1]) { T temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
这里我们需要把SortHelper定义类泛型类:
//定义泛型类SortHelper 这里“where T:IComparable” 是给类型参数T一个限制 -- 参数类型必须实现IComparable接口,否则无法通过编译 public class SortHelper<T> where T:IComparable { public void BubbleSort(T[] arr) { int length = arr.Length; for (int i = 0; i < length-1; i++) { for (int j = 0; j < length-1-i; j++) { if (arr[j].CompareTo(arr[j+1])>0) { T temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
测试一下:
static void Main(string[] args) { SortHelper<byte> sorter = new SortHelper<byte>(); byte[] a = { 4,5,1,3,2,8,5,0,2}; sorter.BubbleSort(a); SortHelper<int> sorter1 = new SortHelper<int>(); int[] b = { 4, 5, 1, 3, 2, 8, 5, 0, 2 }; sorter1.BubbleSort(b); //输出省略 }
输出:
0,1,2,2,3,4,5,5,8
0,1,2,2,3,4,5,5,8
3,为什么不用object
1)泛型不需要装箱和拆箱,性能好
2)泛型是类型安全的
3)泛型可以二进制代码重用
4,泛型约束:约束声明了泛型要求的类型参数的特征。
为了声明一个约束,需要使用where关键字,后跟一对”参数:要求”.其中,”参数”必须是泛型类型中定义的一个参数,而”要求”用于限制类型从
中”派生”的类或接口,或者限制必须存在一个默认构造器,或者限制使用一个引用/值类型约束.
约束的例子可以看这里:http://www.cnblogs.com/smiler/p/3163312.html
5,协变和逆变
示例代码从这里抄的:http://www.cnblogs.com/keiling/p/3672346.html
相关文章推荐
- C#Winformd读取excel文件数据转化为DataTable
- C#串口通信、单片机
- C#与51单片机串口通信
- 如何用C#的serialport类接收单片机发送的数据
- c# 2016QQ自动登录程序
- C#设计模式—解释器模式
- C#设计模式—代理模式
- C# 多线程的自动管理(线程池)
- C#多线程学习 之 线程池[ThreadPool]
- C#手动回收内存的简单方法
- 简简单单学会C#位运算
- C# 读写XML
- C#—文件操作—实验12.3
- C#写入和读出文本文件
- C#:将DataTable内容写入到CSV文件 与 将CSV文件内容读取到DataTab (转)
- 保存文件打开文件对话框
- c#读取xml文件
- 【开源】.Net 动态脚本引擎NScript
- C# 静态类与非静态类、静态成员的区别
- C#—目录操作