4.5 Type Parameters
A type parameter is an identifier designating a value type or reference type that the parameter is bound to at runtime.
type-parameter: identifier
Since a type parameter can be instantiated with many different actual type arguments, type parameters have slightly different operations and restrictions than other types:
- A type parameter cannot be used directly to declare a base class (§10.2.4) or interface (§13.1.3).
- The rules for member lookup on type parameters depend on the constraints, if any, applied to the type parameter. They are detailed in §7.4.
- The available conversions for a type parameter depend on the constraints, if any, applied to the type parameter. They are detailed in §6.1.10 and §6.2.6.
- The literal null cannot be converted to a type given by a type parameter, except if the type parameter is known to be a reference type (§6.1.10). However, a default expression (§7.6.13) can be used instead. In addition, a value with a type given by a type parameter can be compared with null using == and != (§7.10.6) unless the type parameter has the value type constraint.
- A new expression (§7.6.10.1) can be used with a type parameter only if the type parameter is constrained by a constructor-constraint or the value type constraint (§10.1.5).
- A type parameter cannot be used anywhere within an attribute.
- A type parameter cannot be used in a member access (§7.6.4) or type name (§3.8) to identify a static member or a nested type.
- In unsafe code, a type parameter cannot be used as an unmanaged-type (§18.2).
As a type, type parameters are purely a compile-time construct. At runtime, each type parameter is bound to a runtime type that was specified by supplying a type argument to the generic type declaration. Thus the type of a variable declared with a type parameter will, at runtime, be a closed constructed type (§4.4.2). The runtime execution of all statements and expressions involving type parameters uses the actual type that was supplied as the type argument for that parameter.