您的位置:首页 > 编程语言 > C#

《C#高级编程》读书笔记(三):关于泛型

2016-06-25 10:26 309 查看
一开始我觉着这本书太厚了,直到看到泛型这一章,发现这本书真不够,毕竟要把一个复杂的概念讲透,没一定的篇幅是不可能的。

泛型这个概念困扰我很久了,所以我把这章翻来覆去看了好几遍,又去网上找了一些文章,算是搞明白了。

先看看泛型的概念:“通过参数化类型来实现在同一份代码上操作多种数据类型。利用“参数化类型”将类型抽象化,从而实现灵活的复用”。所以,有了泛型,就可以创建独立于被包含类型的类和方法了。不必给不同的类型编写功能相同的许多方法或类,只创建一个方法或类即可。

废话少说,来看代码:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: