2.1泛型类型声明
泛型类声明是一种类声明,只不过它比类多声明类型参数列表和类型参数约束语句。
只有提供类型参数列表,这个类声明才能提供类型参数化约束语句;提供了类型参数列表的类声明就是一个泛型类声明,此外任何嵌入到泛型类声明/泛型结构声明中的类,自身也是一个泛型类声明,因为它们必须提供包含类型的类型参数以创建构造类型。
构造类型可以是一个/多个参数,例如List<T>,被称为开放构造类型;也可不使用类型参数来构造类型,例如List<int>,被称为封闭构造类型。
构造类型不可被重载,也就是说,和普通类型一样,在一个作用域,泛型类型必须被唯一地命名;但在非限定类型名字查找中使用的类型查找规则和成员访问,确实考虑到了类型参数的个数。
2.1.1 类型参数
类型参数在类声明上提供,每个类型参数都是一个简单的标识符,它指定用来创建一个构造类型的类型参数的占位符,即为后面将要被提供的类型的占位符,被提供的类型才是实际的类型,即类型实参。
类声明中的每个类型参数在类的声明空间定义了一个名字,这个名字不能和另一个类型参数/类中成员具有相同的名字,更不能和类型自身有相同的名字;类型参数的作用域包括基类、类型参数约束语句、类体;与类成员不同的是,它不能扩展到派生类。
由于类型参数可以被许多不同的实际类型参数所实例化,所以类型参数与其他类型相比,略微有些不同的操作和限制:
*.类型参数不能用于直接声明一个基类型或接口;
*.对于在类型参数上的成员查找规则,如果约束存在,则依赖于应用到该类型参数的约束;
*.有效的类型参数转换依赖于应用到该类型参数上的约束(如果有的话);
*.文本null不能被转换到由类型参数所给定的类型,除非类型参数是由一个类约束所约束的,但可以使用一个默认值表达式代替;
*.由一个类型参数给定的类型的值可以使用"=="和"!="于null进行比较;
*.如果类型参数通过一个构造函数约束被约束,则new表达式只能为类型参数所使用;
*.类型参数不能用于特性内的任何地方;
*.类型参数不能用于成员访问,也不能标识号一个静态成员或嵌套类型的类型名字;
*.在不安全代码中,类型参数不能用做非托管类型。
作为一种类型,类型参数纯粹只是一个编译时构件;在运行时,每个类型参数被绑定到运行时类型,这是通过泛型类型声明所提供的类型实参而指定的;为此,在运行时,使用类型参数声明的变量类型是一个封闭类型。
2.1.2 实例类型
每个类声明都有与之关联的构造类型,即实例类型;对于一个泛型类声明,实例类型是通过创建一个来自于类型声明的构造类型而形成的;由于实例类型使用类型参数,因此只有在类型参数的作用域内,实例类型才有效。实例类型在类声明中是this的类型;对于非泛型类,实例类型就是声明类型。
2.1.3 基类规范
在类声明中指定的基类/基接口可以是一个构造类型/构造接口类型,但基类/基接口自身不能是类型参数,但在其作用域可以包含类型参数。
泛型类声明不能使用System.Attribute作为直接或间接基类。
在一个类中的方法如果重写或实现了基类或接口的方法,那么它必须为特定类型提供合适的方法:
2.1.4 泛型类的成员
泛型类的所有成员都可以使用封闭类中的类型参数,不论是直接使用还是作为构造类型的一部分。运行时实际类型参数会将其代替。
在实例函数成员之内,this的类型就是声明的实例类型。
除了使用类型参数作为类型之外,在泛型类声明中的成员也遵循和非泛型类成员相同的规则。其他的后面会写到~
2.1.5 泛型类中的静态字段
在一个泛型类声明中的静态变量,在相同封闭构造类型的所有实例中是被共享的,但在不同封闭构造类型的实例中,不被共享。有点绕口,举个栗子:
2.1.6 泛型类中的静态构造函数
泛型类中的静态构造函数用于初始化静态字段,为每个从特定泛型类声明中创建的不同的封闭构造类型,执行其他初始化。泛型类型声明的类型参数在作用域之内,可以在静态构造函数体内被使用。
当发生下面情况,则会有一个新的封闭构造函数类类型被首次初始化:
*.一个封闭构造类型的实例被创建;
*.封闭构造类型的任何静态成员被引用。
为了初始化一个新的封闭构造类类型,首先那个特定封闭类型的一组新静态字段将会被创建,每个静态字段都会被初始化为其的默认值;接着,将为这些静态字段执行静态字段初始化器。最后将执行静态构造函数。
由于静态构造函数将为每个封闭构造类类型执行一次,所以对于无法在编译时通过约束进行的检查来说,在运行时去实施运行时检查将会很方便。
这是使用静态构造函数检查一个类型参数是否是一个引用类型。
2.1.7 访问受保护的成员
在一个泛型类声明中,通过从泛型类构造的任何类型的实例,都可以对继承的受保护实例成员进行访问;尤其是访问被指定了protected和protected internal的实例成员的规则,进行了扩充:在一个泛型类G中,对于一个继承的受保护的实例成员M,可以使用E.M形式的基本表达式对一个继承的受保护实例成员进行访问,前提E的类型是从G构造的类类型,或是一个继承于从G构造的类类型的类类型。
2.1.8 在泛型类中重载
发
原文地址:https://www.cnblogs.com/dreamoffire/p/10173840.html