泛型概述
泛型是用于处理算法、数据结构的一种编程方法。泛型的目标是采用广泛适用和可交互性的形式来表示算法和数据结构,以使它们能够直接用于软件构造。泛型类、结构、接口、委托和方法可以根据它们存储和操作的数据类型来进行参数化。泛型可在编译时提供强大的类型检查,减少数据类型之间的显式转换、装箱操作和运行时的类型检查等。泛型类和泛型方法同时具备可重用性、类型安全和效率高等特性,这是非泛型类和非泛型方法所无法具备的。
? 技巧:泛型通常用在集合和在集合上运行的方法中。
类型参数T
泛型的类型参数T可以看作是一个占位符,它不是一种类型,而仅代表某种可能的类型。在定义泛型时,T出现的位置可以在使用时用任何类型来代替。类型参数T的命名规则如下:
使用描述性名称命名泛型类型参数,除非单个字母名称完全可以让人了解它表示的含义,而描述性名称不会有更多的意义。
例 使用代表一定意义的单词作为类型参数T的名称,代码如下。
public interface ISessionChannel<Session>
public delegate TOutput Converter<Input, Output>
将T作为描述性类型参数名的前缀。
例 使用“T”作为类型参数名的前缀,代码如下。
public interface ISessionChannel<TSession>
{
TSession Session { get; }
}
泛型接口的声明及使用
泛型接口的声明形式如下:
interface 【接口名】<T>
{
【接口体】
}
声明泛型接口时,与声明一般接口的唯一区别是增加了一个<T>。一般来说,声明泛型接口与声明非泛型接口遵循相同的规则。泛型类型声明所实现的接口必须对所有可能的构造类型都保持唯一,否则无法确定该为某些构造类型调用哪个方法。
例 创建一个控制台应用程序。首先创建一个Factory类,在此类中建立一个CreateInstance方法;然后再创建一个泛型接口,在这个泛型接口中调用CreateInstance方法;根据类型参数T,获取其类型。代码如下:(实例位置:光盘/TM/第17章/例17.6)
//创建一个泛型接口
public interface IGenericInterface<T>
{
T CreateInstance(); //接口中调用CreateInstance方法
}
//实现上面泛型接口的泛型类
//派生约束where T : TI(T要继承自TI)
//构造函数约束where T : new()(T可以实例化)
public class Factory<T, TI> : IGenericInterface<TI> where T : TI, new()
{
public TI CreateInstance() //创建一个公共方法CreateInstance
{
return new T();
}
}
class Program
{
static void Main(string[] args)
{
//实例化接口
IGenericInterface<System.ComponentModel.IListSource> factory =new Factory<System.Data.DataTable, System.ComponentModel.IListSource>();
//输出指定泛型的类型
Console.WriteLine(factory.CreateInstance().GetType().ToString());
Console.ReadLine();
}
}
——摘自《C#编程词典》