首页 > Python基础教程 >
-
C#教程之泛型T的理解
泛型的参数类型T可以看做是一个占位符(标准名称叫类型参数Type Parameter),它不是一个类型,它仅代表某种可能的类型。T可以在使用时用任何类型来代替。
1.T的描述性名称不会有任何意义
Tsession只是一个名字。
2.泛型接口
interface 【接口名】<T>
{ 【接口体】}
与一般接口声明的唯一区别就是加了一个<T>。
以下是六种类型约束:
T:结构 -- 类型必须是值类型。
T:类 -- 类型参数必须是引用类型。
T:new() -- 类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new()的约束必须最后指定。
T:<基类名> -- 类型参数必须是指定的基类或者派生自指定的基类。
T:<接口名称> -- 类型参数必须是指定的接口或实现指定的接口。
T:U --为T提供的类型参数必须是为U提供的参数或派生自为U提供的参数。
下面是一个比较完整的例子:
这是一个简单的book类,我们要实现对这个类对象的排序
public class Book {
private int id;
private string title;
public Book() { }
public Book(int id, string title) {
this.id = id;
this.title = title;
}
public int Id {
get { return id; }
set { id = value; }
}
public string Title {
get { return title; }
set { title = value; }
}
}
然后我们想通过一个排序类中的方法来对book类对象排序:
Book[] bookArray = new Book[2];
Book book1 = new Book(124, ".Net之美");
Book book2 = new Book(45, "C# 3.0揭秘");
bookArray[0] = book1;
bookArray[1] = book2;
SortHelper<Book> sorter = new SortHelper<Book>();
sorter.BubbleSort(bookArray);
foreach (Book b in bookArray) {
Console.WriteLine("Id:{0}", b.Id);
Console.WriteLine("Title:{0}\n", b.Title);
}
那么我们要通过一个泛型方法BubbleSort来对book对象比较和排序,那就意味着我们要在book类中实现IComparable接口中的CompareTo方法了:
public class Book :IComparable {
// CODE:上面的实现略
public int CompareTo(object obj) {
Book book2 = (Book)obj;
return this.Id.CompareTo(book2.Id);
}
}
为了要求类型参数T必须实现IComparable接口,我们像下面这样重新定义SortHelper<T>,这样才能保证传入类型可以进行比较。这就是泛型约束:
public class SortHelper<T> where T:IComparable
{
public void BubbleSort(T[] array) {
int length = array.Length;
for (int i = 0; i <= length - 2; i++) {
for (int j = length - 1; j >= 1; j--) {
// 对两个元素进行交换
if (array[j].CompareTo(array[j - 1]) < 0 ) {
T temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
}
}
}
}
}
上面定义说明类型参数T必须实现ICompareble接口,否则将无法通过编译,从而保证了方法体可以正确运行。因为现在T已经实现了IComparable,而数组array中的成员是T的实例,所以当你在array[i]后面点击小数点“.”时,VS智能提示将会给出IComparable的成员,也就是CompareTo()方法。
到现在为止我们就可以运行并得到正确结果啦。
3.泛型方法:
在如上的SortHelper里面,我们目前只有一个BubbleSort方法,他需要传入的T实现IComparable接口,那么考虑一下如果我们这个SortHelper类还有别的方法,并不需要调用的类实现这个接口,那么我们在上面加的 where T:IComparable就会使我们陷入一个困难中。
这时我们可以把这个泛型约束加在方法上,而不是加在类上:
public void BubbleSort<T>(T[] array) where T : IComparable {
// CODE:实现略
}
这样调用的其他类(不实现IComparable接口)可以使用这个类的其他方法,并且看不到这个BubbleSort方法了。
参考资料:
C#中的泛型 - 学习虾 - 博客园