.NET泛型术语 - 打开/关闭,未绑定/构造

时间:2011-02-02 15:52:16

标签: .net generics

.NET泛型术语有点含糊不清。更糟糕的是 - 它似乎在不同来源中含糊不清地使用。基本上不清楚的是这4个术语之间的关系(与“类型”有关):

  1. 关闭
  2. 未结合的
  3. 构造
  4. 我了解List<T>已打开且List<int>已关闭。但是真正与开放/封闭类型相关的“构造”和“未绑定”是什么?

1 个答案:

答案 0 :(得分:21)

来自language specification

  

4.4构造类型

     

泛型类型声明本身,   表示未绑定的泛型类型   被用作形成许多人的“蓝图”   不同的类型,通过申请   类型参数。类型参数是   写在尖括号内(&lt;和&gt;)   紧跟通用类型的名称。包含的类型   至少有一个类型参数叫做a   构造类型。构造类型   可以在大多数地方使用   类型名称可以使用的语言   出现。未绑定的泛型类型可以   只能在一个内部使用   typeof-expression(§7.6.11)。   [...]

     

4.4.2打开和关闭类型

     

所有类型都可以归类为   打开类型已关闭类型。一个开放的   type是涉及类型的类型   参数。更具体地说:

     

•A   type参数定义一个开放类型。

     

•如果和,数组类型是开放类型   只有当它的元素类型是开放的   类型。

     

•构造类型是开放的   当且仅当一个或多个时,才输入   type参数是一个开放类型。一个   构造嵌套类型是开放的   当且仅当一个或多个时,才输入   类型参数或类型参数   其含有的类型是开放的   类型。

     

封闭类型是一种类型   不是开放式的。   [...]

     

4.4.3绑定和未绑定类型

     

术语未绑定类型是指非泛型   类型或未绑定的泛型类型。该   术语绑定类型是指a   非泛型类型或构造的   类型。未绑定类型是指   由类型声明声明的实体。   未绑定的泛型类型本身不是   一个类型,不能用作类型   变量,参数或回报   值,或作为基本类型。唯一的   构造中的未绑定泛型   type可以引用的是typeof   表达式(第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相关联:IsGenericTypeIsGenericTypeDefinitionContainsGenericParameters

(根据语言规范,这些测试不是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<>'s base type.