.NET generics терминология - открытая/закрытая, несвязанная/построенная

Терминология .NET generics немного неоднозначна. Хуже того - кажется, что оно используется неоднозначно и по-разному в разных источниках. В основном неясно, являются ли отношения между этими 4 терминами (относительно "Тип" ):

  • откройте
  • закрыт
  • несвязанный
  • построен

Я понимаю, что List<T> открыт и List<int> закрыт. Но что действительно "построено" и "несвязано" по отношению к открытым/закрытым типам?

Ответы

Ответ 1

Из спецификация языка:

4.4 Построенные типы

Объявление типового типа, само по себе, обозначает несвязанный общий тип, который используется в качестве "плана" для формирования многих различных типов, путем применения аргументы типа. Аргументы типа записанные в угловых скобках (< и > ) сразу после имени родового типа. Тип, который включает по крайней мере один аргумент типа называется построенный тип. Построенный тип может использоваться в большинстве мест в язык, на котором имя типа может появляются. Несвязанный общий тип может используется только в пределах typeof-expression (§7.6.11). [...]

4.4.2 Открытые и закрытые типы

Все типы могут быть классифицированы как открытые типы или закрытые типы. Открытая type - тип, который включает тип параметры. Более конкретно:

• A type определяет открытый тип.

• Тип массива - открытый тип if и только если его тип элемента является открытым тип.

• Построенный тип является открытым типа, если и только если один или несколько его type - открытый тип. построенный вложенный тип является открытым типа, если и только если один или несколько его аргументы типа или аргументы типа его содержащего типа (ов) является открытым тип.

Закрытый тип - это тип, который не открытый тип. [...]

4.4.3 Связанные и несвязанные типы

Термин несвязанный тип относится к неэквивалентным тип или несвязанный общий тип. термин связанный тип относится к не общий тип или построенный тип. Несвязанный тип относится к объект, объявленный объявлением типа. Несвязанный общий тип сам по себе тип и не может использоваться как тип переменной, аргументом или возвратом значение или как базовый тип. Единственный конструкции, в которой несвязанный общий тип может ссылаться на тип выражение (§7.6.11).


Вот пример, который я подумал:

// 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> { .. } 

И вот попытка связать это с API отражения, используя соответствующие свойства: IsGenericType, IsGenericTypeDefinition и ContainsGenericParameters

(Эти тесты не являются 100% -ными прогнозами каждого "вида" в соответствии с спецификацией языка).

+----------+---------------------+-----------+--------------+-------------------+
|   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<> base type.