Members of constructed types
The non-inherited members of a constructed type are obtained by substituting, for each type-parameter in the member declaration, the corresponding type-argument of the constructed type. The substitution process is based on the semantic meaning of type declarations, and is not simply textual substitution. For example, given the generic class declaration class Gen<T,U> public void G(int i, T t, Gen<U,T> gt) {...} public U Prop { get {...} set {...} } public int H(double d) {...} the constructed type Gen<int[],IComparable<string>> has the following members: public int[,][] a; public void G(int i, int[] t, Gen<IComparable<string>,int[]> gt) {...} public IComparable<string> Prop { get {...} set {...} } public int H(double d) {...} The type of the member a in the generic class declaration Gen is “two-dimensional array of T”, so the type of the member a in the constructed type above is “two-dimensional array of one-dimensional array of int”, or int[,][]. Within instance function members, the type of this is the instance type (§10.3.1) of the containing declaration. All members of a generic class can use type parameters from any enclosing class, either directly or as part of a constructed type. When a particular closed constructed type (§4.4.2) is used at run-time, each use of a type parameter is replaced with the actual type argument supplied to the constructed type. For example: class C<V> public C(V x) { class Application C<double> x2 = new C<double>(3.1415);
|