假设需要一个两个整形变量交换的函数,我们很快就可以嗒嗒嗒嗒的敲出下面的 Swap 函数:
void Swap(ref int lhs, ref int rhs)
{
int temp = lhs;
lhs = rhs;
rhs = temp;
}
随着项目进展,我们发现,需要用到 Swap 函数的不仅是整形,变量 还有字符串,于是我们我又嗒嗒嗒嗒的重载 Swap 函数如下:
void Swap(ref string lhs, ref string rhs)
{
string temp = lhs;
lhs = rhs;
rhs = temp;
}
接下来的开发中,我们又发现还有自定义的结构体,类等等等等都要用到 Swap 函数。如果我们为每一种类型都实现一个相应的 Swap 函数的话,各个版本的 Swap 函数数据类型不同外,其它完完全全一样。也就是说,项目中存在大量的代码重复。能不能之实现一个能够适用于不同数据类型的 Swap 函数,消除这种代码冗余,从而减少工作量,提高开发效率呢?
类型转换
在 C# 中 所有的类型都直接或间接的继承自 System.Object 类。换句话说,所有的类型都可以转换为 Object 类。这为我们前面的问题提供了一个解决方案——实现一个以 Object 为类型参数的 Swap 函数。其实现如下:
void Swap(ref object lhs, ref object rhs)
{
object temp = lhs;
lhs = rhs;
rhs = temp;
}
调用的代码如下:
//a, b 为要传入 Swap 函数的变量
object objA = a;
object objB = b;
Swap(ref objA, ref objB);
//T 为变量 a 和 b 的数据类型
a = (T)objA;
b = (T)objB;
这一实现利用类型转换有效的重用了 Swap 的代码,但有两点不足。
首先是性能问题。每次调用 Swap 函数前,需要对其参数进行一次向上的转型;调用完之后,又要对其进行一次向下的转型。如果需要多次调用 Swap 函数(比如在一个很大的循环中),转型带来的开销是想当可观的,特别是当参数为值类型的时候。
第二是,无法提供编译时类型检查。下面的例子虽然能通过编译,但运行时会出现异常:
string a = “This is a string”;
int b = 0;
object objA = a;
object objB = b;
Swap(ref objA, ref objB); //可以编译
a = (string)objA; //出现运行时异常
b = (ing)objB;
针对以上两点不足,C# 2.0 提出了泛型。
泛型
泛型是C# 2.0 提供的延迟类和函数中数据类型的定义,直到客户代码声明或实例化该数据类型。
泛型版的 Swap 函数实现如下
void Swap<T>(ref T lhs, ref T rhs)
{
T temp = lhs;
lhs = rhs;
rhs = temp;
}
上例中的类型参数 T 可以实例化为任意数据类型。相对于通过类型转换重用 Swap 函数,它且不需要类型转换,有效的提高性能。而且,它还能提供编译时类型检查。调用语法与普通函数调用完全一样。
泛型的优势
从上面例子可以看出,使用泛型具有如下三点优势:
Ø 避免重复代码,最大化代码重用
Ø 避免无谓的类型转换,提高性能
Ø 提供编译时类型检查,具有类型安全性