泛型接口
使用泛型可以定义接口,在按口中定义的方法可以带泛型参数。在链表的示例中,就实现了
IEnunmble<out T>接口,它定义了GetEnumeratorO方法,以返回IEnummtor<out T>。.NET为不同的情况提供了许多泛型接口,例如ICompamble<T>、ICollection<T>和ExtensibleObject<T>。同一个接口常常存在比较老的非泛型版本,例如,.NET1.0 有基于对象的IComparable接口。IComparable<int T>基于一个泛型类型:
pub1ic interface IComparable<in T>
{
int CompareTo(T other);
}
协变和抗变
在.NET4之前,泛型接口是不变的。.NET4通过协变和抗变为泛型接口和泛型委托添加了一个重要的扩展。协变和抗变指对参数和返回值的类型进行转换。在.NET中,参数类型是协变的,方法的返回类型是抗变的。
泛型结构
与类相似,结构也可以是泛型的。它们非常类似于泛型类,只是没有继承特性。本节介绍泛型
结构Nullable<T>,它由.NET Framework定义。
.NET Fmmework中的一个泛型结构是Nullable<T>。数据库中的数字和编程语言中的数字有显
著不同的特征,因为数据库中的数字可以为空,而C#中的数字不能为空。int32是一个结构,而结构的实现同值类型,所以结构不能为空。这个问题不仅存在于在数据库中,也存在于把XML数据映射到,NET类型。这种区别常常令人很头痛,映射数据也要多做许多辅助工作。一种解决方案是把数据库和XML文件中的数字映射为引用类型,因为引用类型可以为空值。但这也会在运行期间带来额外的系统开销。使用Nullable<T>结构很容易解决这个问题。
结构Nullable<T>定义了一个约束:其中的泛型类型T必须是一个结构。把类定义为泛型类型
后,就没有低系统开销这个优点了,而且因为类的对象可以为空,所以对类使用Nullable<T>类型是没有意义的。除了Nullable<T>定义的T类型之外,唯一的系统开销是hasValue布尔字段,它确定是设置对应的值,还是使之为空。除此之外,泛型结构还定义了只读属性hasValue和value,以及一些操作符重载。把Nullable<T>类型强制转换为T类型的操作符重载是显式定义的,因为当hasValue为false时,它会抛出一个异常。强制转换为Nullable<T>类型的操作符重载定义为隐式的,因为它总是能成功地转换。
使用泛型可以定义接口,在按口中定义的方法可以带泛型参数。在链表的示例中,就实现了
IEnunmble<out T>接口,它定义了GetEnumeratorO方法,以返回IEnummtor<out T>。.NET为不同的情况提供了许多泛型接口,例如ICompamble<T>、ICollection<T>和ExtensibleObject<T>。同一个接口常常存在比较老的非泛型版本,例如,.NET1.0 有基于对象的IComparable接口。IComparable<int T>基于一个泛型类型:
pub1ic interface IComparable<in T>
{
int CompareTo(T other);
}
协变和抗变
在.NET4之前,泛型接口是不变的。.NET4通过协变和抗变为泛型接口和泛型委托添加了一个重要的扩展。协变和抗变指对参数和返回值的类型进行转换。在.NET中,参数类型是协变的,方法的返回类型是抗变的。
泛型结构
与类相似,结构也可以是泛型的。它们非常类似于泛型类,只是没有继承特性。本节介绍泛型
结构Nullable<T>,它由.NET Framework定义。
.NET Fmmework中的一个泛型结构是Nullable<T>。数据库中的数字和编程语言中的数字有显
著不同的特征,因为数据库中的数字可以为空,而C#中的数字不能为空。int32是一个结构,而结构的实现同值类型,所以结构不能为空。这个问题不仅存在于在数据库中,也存在于把XML数据映射到,NET类型。这种区别常常令人很头痛,映射数据也要多做许多辅助工作。一种解决方案是把数据库和XML文件中的数字映射为引用类型,因为引用类型可以为空值。但这也会在运行期间带来额外的系统开销。使用Nullable<T>结构很容易解决这个问题。
结构Nullable<T>定义了一个约束:其中的泛型类型T必须是一个结构。把类定义为泛型类型
后,就没有低系统开销这个优点了,而且因为类的对象可以为空,所以对类使用Nullable<T>类型是没有意义的。除了Nullable<T>定义的T类型之外,唯一的系统开销是hasValue布尔字段,它确定是设置对应的值,还是使之为空。除此之外,泛型结构还定义了只读属性hasValue和value,以及一些操作符重载。把Nullable<T>类型强制转换为T类型的操作符重载是显式定义的,因为当hasValue为false时,它会抛出一个异常。强制转换为Nullable<T>类型的操作符重载定义为隐式的,因为它总是能成功地转换。