Skip to content

Latest commit

 

History

History
168 lines (129 loc) · 8.53 KB

ii.10.1.7-generic-parameters-genpars.md

File metadata and controls

168 lines (129 loc) · 8.53 KB

II.10.1.7 Generic parameters (GenPars)

Generic parameters are included when defining a generic type.

GenPars ::=
GenPar [ ',' GenPars ]

The GenPar non-terminal has the following production:

GenPar ::=
[ GenParAttribs ]* [ '(' [ GenConstraints ] ')' ] Id
GenParAttribs ::=
'+' | '-' | class | valuetype | .ctor

+ denotes a covariant generic parameter (§II.9.5).

- denotes a contravariant generic parameter (§II.9.5).

class is a special-purpose constraint that constrains Id to being a reference type. [Note: This includes type parameters which are themselves constrained to be reference types through a class or base type constraint. end note]

valuetype is a special-purpose constraint that constrains Id to being a value type, except that that type shall not be System.Nullable<T> or any concrete closed type of System.Nullable<T>. [Note: This includes type parameters which are themselves constrained to be value types. end note]

.ctor is a special-purpose constraint that constrains Id to being a concrete reference type (i.e., not abstract) that has a public constructor taking no arguments (the default constructor), or to being a value type. [Note: This includes type parameters which are, themselves, constrained either to be concrete reference types, or to being a value type. end note]

class and valuetype shall not both be specified for the same Id.

[Example:

.class C< + class .ctor (class System.IComparable`1<!0>) T > { … }

This declares a generic class C<T>, which has a covariant generic parameter named T. T is constrained such that it must implement System.IComparable`1<T>, and must be a concrete class with a public default constructor. end example]

Finally, the GenConstraints non-terminal has the following production:

GenConstraints ::=
Type [ ',' GenConstraints ]

There shall be no duplicates of Id in the GenPars production.

[Example: Given appropriate definitions for interfaces I1 and I2, and for class Base, the following code defines a class Dict that has two generic parameters, K and V, where K is constrained to implement both interfaces I1 and I2, and V is constrained to derive from class Base:

.class Dict`2<(I1,I2)K, (Base)V> { … }

end example]

The following table shows the valid combinations of type and special constraints for a representative set of types. The first set of rows (Type Constraint System.Object) applies either when no base class constraint is specified or when the base class constraint is System.Object. The symbol ✓ means "set", the symbol ✗ means "not set", and the symbol * means "either set or not set" or "don't care".

Type Constraint Special Constraint Meaning
class valuetype .ctor
(System.Object) Any type
Any reference type
Any reference type having a default constructor
* Any value type except System.Nullable<T>
Any type with a public default constructor
* Invalid
System.ValueType Any value type including System.Nullable<T>
* Any value type except System.Nullable<T>
Any value type and System.ValueType, and System.Enum
System.ValueType and System.Enum only
Not meaningful: Cannot be instantiated (no instantiable reference type can be derived from System.ValueType)
* Invalid
System.Enum Any enum type
*
Any enum type and System.Enum
System.Enum only
Not meaningful: Cannot be instantiated (no instantiable reference type can be derived from System.Enum)
* Invalid
System.Exception (an example of any non-special reference Type) System.Exception, or any class derived from System.Exception
Any System.Exception with a public default constructor
System.Exception, or any class derived from System.Exception. This is exactly the same result as if the class constraint was not specified
Any Exception with a public default constructor.
* Not meaningful: Cannot be instantiated (a value type cannot be derived from a reference type)
* Invalid
System.Delegate System.Delegate, or any class derived from System.Delegate
Not meaningful: Cannot be instantiated (there is no default constructor)
System.Delegate, or any class derived from System.Delegate
Any Delegate with a public .ctor. Invalid for known delegates (System.Delegate)
* Not meaningful: Cannot be instantiated (a value type cannot be derived from a reference type)
* Invalid
System.Array Any array
* Not meaningful: Cannot be instantiated (no default constructor)
Any array
* Not meaningful: Cannot be instantiated (a value type cannot be derived from a reference type)
* Invalid

[Example: The following instantiations are allowed or disallowed, based on the constraint. In all of these instances, the declaration itself is allowed. Items marked Invalid indicate where the attempt to instantiate the specified type fails verification, while those marked Valid do not.

.class public auto ansi beforefieldinit Bar`1<valuetype T>
   
Valid ldtoken class Bar`1<int32>
Invalid ldtoken class Bar`1<class [mscorlib]System.Exception>
Invalid ldtoken class Bar`1<Nullable`1<int32>>
Invalid ldtoken class Bar`1<class [mscorlib]System.ValueType>
.class public auto ansi beforefieldinit 'Bar`1'<class T>
   
Invalid ldtoken class Bar`1<int32>
Valid ldtoken class Bar`1<class [mscorlib]System.Exception>
Invalid ldtoken class Bar`1<valuetype [mscorlib]System.Nullable`1<int32>>
Valid ldtoken class Bar`1<class [mscorlib]System.ValueType>
.class public auto ansi beforefieldinit Bar`1<(class  [mscorlib]System.ValueType) T>
   
Valid ldtoken class Bar`1<int32>
Invalid ldtoken class Bar`1<class [mscorlib]System.Exception>
Valid ldtoken class Bar`1<valuetype [mscorlib]System.Nullable`1<int32>>
Valid ldtoken class Bar`1<class [mscorlib]System.ValueType>
.class public auto ansi beforefieldinit Bar`1<class (int32)> T>
   
Invalid ldtoken class Bar`1<int32>
Invalid ldtoken class Bar`1<class [mscorlib]System.Exception>
Invalid ldtoken class Bar`1<valuetype [mscorlib]System.Nullable`1<int32>>
Invalid ldtoken class Bar`1<class [mscorlib]System.ValueType>

Note: This type cannot be instantiated as no reference type can extend int32

.class public auto ansi beforefieldinit Bar`1<valuetype (class [mscorlib]System.Exception)> T>
   
Invalid ldtoken class Bar`1<int32>
Invalid ldtoken class Bar`1<class [mscorlib]System.Exception>
Invalid ldtoken class Bar`1<valuetype [mscorlib]System.Nullable`1<int32>>
Invalid ldtoken class Bar`1<class [mscorlib]System.ValueType>

Note: This type cannot be instantiated as no value type can extend System.Exception

.class public auto ansi beforefieldinit Bar`1<.ctor (class Foo) T>

where Foo has no public .ctor, but FooBar, which derives from Foo, has a public .ctor:

   
Invalid ldtoken class Bar`1<class Foo>
Valid ldtoken class Bar`1<class FooBar>

end example]