15

.NET generics terminology is a bit ambiguous. Even worse - it seems to be used ambiguously and differently in different sources. What basically is not clear is relationships between these 4 terms (in relation to "Type"):

  1. open
  2. closed
  3. unbound
  4. constructed

I understand that List<T> is open and List<int> is closed. But what really is "constructed" and "unbound" in relation to open/closed types?

Konstantin
  • 3,817
  • 4
  • 29
  • 39

1 Answers1

22

From the language specification:

4.4 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. A type that includes 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 (§7.6.11). [...]

4.4.2 Open and closed types

All types can be classified as either open types or closed types. An open type is a type that involves type parameters. More specifically:

• A type parameter defines an open type.

• An array type is an open type if and only if its element type is an open type.

• A constructed type is an open type if and only if one or more of its type arguments is an open type. A constructed nested type is an open type if and only if one or more of its type arguments or the type arguments of its containing type(s) is an open type.

A closed type is a type that is not an open type. [...]

4.4.3 Bound and unbound types

The term unbound type refers to a non-generic type or an unbound generic type. The term bound type refers to a non-generic type or a constructed type. An unbound type refers to the entity declared by a type declaration. An unbound generic type is not itself a type, and cannot be used as the type of a variable, argument or return value, or as a base type. The only construct in which an unbound generic type can be referenced is the typeof expression (§7.6.11).


Here's an example I thought of:

// Foo<T> is an unbound generic type.
class Foo<T> { .. } 

// Bar<K> is an unbound generic type.
// Its base-class Foo<K> is a constructed, open generic type.
class Bar<K> : Foo<K> { .. } 

// IntFoo is not a generic type.
// Its base-class Foo<int> is a constructed, closed generic type.
class IntFoo : Foo<int> { .. } 

And here's an attempt to tie that in with the reflection API, using the relevant properties: IsGenericType, IsGenericTypeDefinition and ContainsGenericParameters

(These tests are not 100% predictive of each "kind" as per the language spec).

+----------+---------------------+-----------+--------------+-------------------+
|   Name   |        Kind         | IsGenType | IsGenTypeDef | ContainsGenParams |
+----------+---------------------+-----------+--------------+-------------------+
| Foo<>    | Unbound             | TRUE      | TRUE         | TRUE              |
| Foo<>*   | Constructed, open   | TRUE      | FALSE        | TRUE              |
| Foo<int> | Constructed, closed | TRUE      | FALSE        | FALSE             |
| IntFoo   | Not generic         | FALSE     | FALSE        | FALSE             |
+----------+---------------------+-----------+--------------+-------------------+
* = Bar<>'s base type.
Community
  • 1
  • 1
Ani
  • 111,048
  • 26
  • 262
  • 307
  • Also see the *Examples* section of the [doc page for `IsGenericType`](http://msdn.microsoft.com/en-us/library/system.type.isgenerictype.aspx). For the new property `IsConstructedGenericType` see a [thread I just started](http://stackoverflow.com/questions/18796119/). – Jeppe Stig Nielsen Sep 14 '13 at 07:44
  • And see [What exactly is an “open generic type” in .NET? (duplicate)](http://stackoverflow.com/questions/2173107/). – Jeppe Stig Nielsen Sep 14 '13 at 07:50