ECMA-334: 25.5 Constructed types
| C# Language Specification |
| © 2006 ECMA International |
25.5 Constructed types
A generic type declaration, by itself, denotes an unbound generic type that is used as a "blueprint" to form
many different types, by way of applying type arguments. The type arguments are written within angle
brackets (< and >) immediately following the name of the generic type declaration. A type that is named
with at least one type argument is called a constructed type. A constructed type can be used in most places
in the language in which a type name can appear. An unbound generic type can only be used within a typeof-expression
(§14.5.11).
Constructed types can also be used in expressions as simple names (§14.5.2) or when accessing a member (§14.5.4).
When a namespace-or-type-name is evaluated, only generic types with the correct number of type parameters are considered. Thus, it is possible to use the same identifier to identify different types, as long as the types have different numbers of type parameters. This is useful when mixing generic and non-generic classes in the same program. [Example:
namespace Widgets { class Queue {…} class Queue<ElementType> {…} } namespace MyApplication { using Widgets; class X { Queue q1; //Non-generic Widgets.Queue Queue<int> q2; // Generic Widgets.Queue } }
end example]
The detailed rules for name lookup in the namespace-or-typename productions is described in §10.8. The resolution of ambiguities in these productions is described in §9.2.3.
A type-name might identify a constructed type even though it doesn’t specify type parameters directly. This can occur where a type is nested within a generic class declaration, and the instance type of the containing declaration is implicitly used for name lookup (§25.1.11). [Example:
class Outer<T> { public class Inner {…} public Inner i; // Type of i is Outer<T>.Inner }
end example]
[Note: In unsafe code, a constructed type shall not be used as an unmanaged-type (§25.2). end note]