泛型将类型参数的概念引入了.Net,当我们需要设计类和方法,并将它们的类型制定推迟到客户端代码声明,并实例化该类型和方法时,可以使用泛型。泛型使之前的想法成为了可能。使用泛型避免了运行时强制转换或装箱操作带来的风险。简单来说,首先制定一个特定符号代替实际类型,当创建该类型的实例时,才指定它的实际类型。
泛型可以让类、结构、委托、接口和方法通过他们所存储和操作的数据的类型被参数化。
为什么要使用泛型?我们以实例来说明:
在上面的代码中,使用的全部都是整型变量,在软件设计中,去求是经常变更的,如果我要求输入的是浮点型该怎么办呢?当然,我们可以把int改为object,并使用强制转换,如下面所示:
我们看到,上面的程序也能够编译通过并运行,但实际上这是非常消耗资源的,因此这种方法并不可用。而泛型就是为了解决这个问题而存在的,使用泛型很简单,看下面的代码:
在泛型实例化后,可以很方便的制定他的修饰符为double或string。
泛型的约束:
为了对客户端代码在实例化时对类型参数加以限制,可以使用泛型的约束,约束是使用where 关键字指定的,共有6种约束类型
约束 | 说明 |
---|---|
T:结构 | 类型参数必须是值类型 。可以指定除 Nullable 以外的任何值类型。有关更多信息,请参见使用可以为 null 的类型(C# 编程指南) 。 |
T:类 | 类型参数必须是引用 类型;这一点也适用于任何类、接口、委托或数组类型。 |
T:new() | 类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。 |
T:<基类名> | 类型参数必须是指定的基类或派生自指定的基类。 |
T:<接口名称> | 类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。 |
T:U | 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束。 |