CLR via C#:泛型

泛型:是CLR和编程语言提供的一种特殊机制,它支持另外一种形式的代码复用(即算法复用)。具有以下特性:
1.泛型的优点具有源代码保护(不用公开泛型源代码),类型安全(必须指定类型实参),更清晰的代码和更佳的性能(避免类型转换以及装箱拆箱等过程)。
2.CLR允许创建泛型引用类型,泛型结构体值类型,泛型接口,泛型委托和泛型函数。
3.C#约定泛型类型参数名至少是以T开头,如T,TKey,TValue,TEventArgs等。
4.具有泛型类型参数的类型叫做开放类型。该类型是不能创建对象的,并且可以在静态构造函数里面限制类型实参。参考代码如下所示:

internal sealed class GenericTypeThatRequireAnEnumType<T>
{
	// 在静态构造函数中限制类型实参必须是枚举类型
	static GenericTypeThatRequireAnEnumType()
	{
		if (!typeof(T).IsEnum)
		{
			throw new ArgumentException("T Must Be A Enum Type");
		}
	}
}

5.所有的泛型类型参数都指定了类型实参的类型叫做封闭类型。该类型是可以创建对象的,并且不同的封闭类型会独自拥有一份开放类型中所有的成员。
6.为泛型类型参数指定类型实参并不会改变继承层次结构。
7.在相同的AppDomain中,当不同程序集中含有同名泛型函数且该函数具有相同泛型类型实参时,CLR只会生成同一份函数代码。
8.在同名泛型函数中,如果泛型类型实参为引用类型的话,CLR会生成同一份函数代码;如果泛型类型实参为值类型的话,CLR会为每个值类型都生成一份函数代码。
9.不指定类型参数的形式调用泛型函数时,编译器会根据类型实参推断调用匹配的泛型函数。

泛型类型同一性:就是简化的类型和封闭类型必须是等价的。具有以下方案:
1.使用using指令来将封闭类型起个别名,此时别名对应的类型就是封闭类型。
2.使用var定义变量来推断实例的封闭类型,此时变量对应的类型就是封闭类型。

泛型类型参数的种类:如下所示:
1.不变量:意味着泛型类型参数不能更改。
2.逆变量:意味着泛型类型参数可以从一个类更改为它的某个派生类。具有以下特性:
1>.泛型类型参数不能为值类型。
2>.C#中用in关键字来标记泛型类型参数。
3>.泛型类型参数只能出现在输入位置,比如作为函数的参数(参数不能用ref或者out关键字)。
3.协变量:意味着泛型类型参数可以从一个类更改为它的某个基类。具有以下特性:
1>.泛型类型参数不能为值类型。
2>.C#中用out关键字来标记泛型类型参数。
3>.泛型类型参数只能出现在输出位置,比如作为函数的返回类型。

约束:指的通过where关键字进行限制能指定成泛型类型实参的数量。具有以下特性:
1.约束可以应用于泛型类型和泛型函数。
2.泛型函数重载跟参数列表中每个参数类型有关,跟泛型类型参数名称以及约束无关。
3.不能指定重写泛型函数的约束,该函数的约束从基函数继承。
4.泛型类型参数可以指定0个或者1个主要约束。具有以下特性:
1>.主要约束类型默认为System.Object类型。
2>.主要约束类型不能为密封的引用类型。当主要约束类型是非密封的引用类型时,泛型类型实参只能是约束类型或者其派生类型。并且不能指定System.Object,System.Array,System.Delegate,System.MulticastDelegate,System.ValueType,System.Enum,System.Void等引用类型作为主要约束类型。
3>.当主要约束为class时,表示泛型类型实参可以为所有引用类型。
4>.当主要约束为struct时,表示泛型类型实参可以为除了Nullable类型外的所有值类型。
5.泛型类型参数可以指定0个或者多个次要约束。具有以下特性:
1>.次要约束用于接口类型时,表示泛型类型实参必须实现该接口。
2>.次要约束用于泛型类型参数时,表示泛型类型实参要么是约束的类型,要么是该类型的派生类型。如

// T是由泛型类型参数TBase约束,那么T久只能是TBase或者其派生类型。
private static List<TBase> ConvertList<T, TBase>(IList<T> list) where T:TBase;

6.泛型类型参数可以指定0个或者1个构造函数约束。具有以下特性:
1>.构造函数约束只能应用公共无参构造函数。
2>.构造函数约束不能和struct主约束一起使用。
3>.构造函数约束表明泛型类型实参是有提供公共无参构造函数的非抽象类型。

可验证性:具有以下特性:
1.当将泛型类型变量转型为泛型约束兼容的类型时,转换操作是合法;否则就是非法。
2.当主约束类型是非密封的引用类型时,将泛型类型变量设为null是合法;否则就是非法。
3.当主约束类型不是struct时,将泛型类型变量与null进行比较是合法;否则就是非法。
4.当主约束是非密封的引用类型或者class类型时,将两个泛型类型变量进行比较是合法,否则就是非法。
5.不能向泛型类型变量应用任何操作符。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章