C# 语言:泛型、打开/关闭、绑定/未绑定、构造

Posted

技术标签:

【中文标题】C# 语言:泛型、打开/关闭、绑定/未绑定、构造【英文标题】:C# Language: generics, open/closed, bound/unbound, constructed 【发布时间】:2011-09-30 05:24:36 【问题描述】:

我正在阅读 Anders Hejlsberg 等人撰写的《C# 编程语言》第 4 版。

有几个定义有点扭曲:

未绑定的泛型类型:泛型类型声明本身表示未绑定的泛型类型...

构造类型:包含至少一个类型参数的类型称为构造类型。

开放类型:开放类型是涉及类型参数的类型。

封闭型:封闭型是不是开放型的类型。

未绑定类型:指非泛型类型或未绑定泛型类型。

绑定类型:指非泛型类型或构造类型。 [注释] ERIC LIPPERT:是的,非泛型类型被认为是绑定的和未绑定的。

问题 1,下面我列出的内容是否正确?

int                     //non-generic, closed, unbound & bound, 
class A<T, U, V>        //generic,     open,   unbound, 
class A<int, U, V>      //generic,     open,   bound, constructed 
class A<int, int, V>    //generic,     open,   bound, constructed
class A<int, int, int>  //generic,     closed, bound, constructed

问题 2,书上说 “未绑定类型是指由类型声明声明的实体。 未绑定的泛型类型本身不是类型,它不能用作变量、参数或返回值的类型,也不能用作基类型。 唯一可以引用未绑定泛型类型的构造是 typeof 表达式(第 7.6.11 节)。” 很好,但是下面是一个可以编译的小测试程序:

public class A<W, X>  

// Q2.1: how come unbounded generic type A<W,X> can be used as a base type?
public class B<W, X> : A<W, X>   

public class C<T,U,V>

    // Q2.2: how come unbounded generic type Dictionary<T, U> can be used as a return value?
    public Dictionary<T,U> ReturnDictionary()  return new Dictionary<T, U>(); 

    // Q2.3: how come unbounded generic type A<T, U> can be used as a return value?
    public A<T, U> ReturnB()  return new A<T, U>(); 

【问题讨论】:

关于我对第二个问题的了解。您只能将 B 类和 C 类给定参数用于模板类类型,因此您只能完全绑定使用它们。 是的,这可能有点误导。显然,您可以在父未绑定类型(具有相同的未绑定泛型参数)的 定义 中使用未绑定类型,但您永远不能自己实例化它。 What exactly is an "open generic type" in .NET?的可能重复 @nawfal 这个问题本身就是重复的。 @Izzy 是的,但是这个标题的方式,我相信那个问题更能说明这一点。 【参考方案1】:

这些是未绑定的泛型类型的示例

List&lt;&gt; Dictionary&lt;,&gt;

它们可以与typeof 一起使用,即以下是有效的表达式:

typeof(List&lt;&gt;) typeof(Dictionary&lt;,&gt;)

这应该回答您的问题 2。关于问题 1,请注意 类型参数 可以是 构造类型类型参数。因此,您的列表应更新如下:

public class MyClass<T, U>   // declares the type parameters T and U

    // all of these are
    // - generic,
    // - constructed (since two type arguments are supplied), and
    // - bound (since they are constructed):

    private Dictionary<T, U> var1;     // open (since T and U are type parameters)
    private Dictionary<T, int> var2;   // open (since T is a type parameter)
    private Dictionary<int, int> var3; // closed

【讨论】:

我认为我的误解是,对于 MyClass,我认为 T & U 不是类型参数,我认为“MyClass”中只有“int”是类型参数. @athos:是的,恰恰相反:int 不是类型参数,但 TU 是。 两者都可以用作类型参数(即,用于替换private Dictionary&lt;_, _&gt; var1中的下划线)。 @athos:Heinzi 是正确的。进一步澄清。 T 和 U 是类型 参数,它们在其中被声明。然后它们可以使用作为类型参数,或者仅仅作为类型使用。以此类推,假设您有:int foo(int x) return bar(x); 这里的“x”是声明它的 foo 的参数和使用它的 bar 调用的参数。类型参数和类型参数的工作方式类似。 @nawfal:它记录在C# language specification 中。例如,第 4.4.3 节指出:“术语 绑定类型 指的是非泛型类型或构造类型。” @MohammedNoureldin 你可以像typeof(List&lt;&gt;) 一样使用它们。如果你深入反思,这样的事情会很方便。例如构造一个泛型类型。有关示例用法,请参阅此答案:***.com/a/8940014/661933【参考方案2】:

Jon 给出了一个很好的答案,here.

不提供技术描述,因为链接答案中的所有内容都完美无缺。在这里仅仅复制它的要点作为答案,它看起来像:

A                             //non generic, bound
A<U, V>                       //generic,     bound,  open,   constructed
A<int, V>                     //generic,     bound,  open,   constructed
A<int, int>                   //generic,     bound,  closed, constructed
A<,> (used like typeof(A<,>)) //generic,     unbound 

在与 Heinzi 讨论后编辑

【讨论】:

以上是关于C# 语言:泛型、打开/关闭、绑定/未绑定、构造的主要内容,如果未能解决你的问题,请参考以下文章

为啥c ++中线程构造函数和绑定的函数签名相同[关闭]

XML 中的 C# 元素未绑定到类

C#控件绑定数据源方式

Android Lint 检查中的“命名空间未绑定”

有人知道 FFMPEG 的一组 C# 绑定吗? [关闭]

C# MVC 使用复选框选项构造视图并将答案自动绑定到对象的正确方法?