C#中是否允许使用泛型类型参数?

4
我想创建以下类片段。
class Lookup<TKey,TValue,TCollection>
where TCollection : ICollection<>
{
    public TCollection<TKey> _KeyCollection;
    public TCollection<TValue> _ValueCollection;
}

这种模式在C#中是否普遍存在?在当前形式下,编译器不喜欢它。似乎无法限制类型参数为通用类型。但是,这似乎是一件合理的事情。有什么技巧可以实现它吗?

注意:此问题特别涉及通用类型和类型约束。它不是寻找解决更广泛应用程序中可能尝试执行的操作的方法。


2
你能提供一下你想如何使用它的示例吗? - Grundy
示例如上。我想公开两个公共字段。它们都必须派生自“ICollection<>”。 - bradgonesurfing
3
在类的其余部分中,您似乎试图将泛型约束为一个“开放的”泛型类型,但实际上是行不通的。 - Damien_The_Unbeliever
那可能就是我要找的答案。如果你想把它作为答案提供,除非有什么高招,否则我会接受它。如果能指出标准中正确的部分,将获得额外加分 :) - bradgonesurfing
@bradgonesurfing 你可以在msdn上查看有关约束的信息,你可以使用 接口名称基类名称,但需要指定泛型参数,因为名称中包含它。 - Grundy
显示剩余6条评论
2个回答

3

您不能将开放式泛型类型作为约束条件。但是,您可以使用封闭的泛型类型:

class Lookup<TKey, TValue, TKeyCollection, TValueCollection>
    where TKeyCollection : ICollection<TKey>
    where TValueCollection : ICollection<TValue>
{
    public TKeyCollection _KeyCollection;
    public TValueCollection _ValueCollection;
}

这可能不太美观,而且有很多类型参数,但这是可行的。


实际上,这是我的真实代码中的解决方法,只不过它太过于通用了。TKeyCollection和TValueCollection可以继承自不同的基类。其中一个可能是List<TKey>,而另一个可能是HashSet<TValue>,这有点太广泛了。 - bradgonesurfing
从理论上讲,您可以通过添加另一个类型参数来限制TKeyCollectionTValueCollection的基础部分,从而将其缩小一些。 您只需要使用非泛型接口(例如IListICollection)。 但是,您将无法确定确切的类型。 - Brian Kintz

3
您无法约束一个泛型类型参数成为一个开放式的泛型类型,而这似乎正是您在类的其余部分尝试使用它的方式。
您要求一个规范参考,但似乎没有一个地方以清晰简洁的方式详细说明。
我所能找到的最好的解释是在第4.5节(来自C# 5.0规范)中:
“作为一种类型,类型参数仅仅是一个编译时的构造。在运行时,每个类型参数都被绑定到一个由提供泛型类型声明的类型参数指定的运行时类型。因此,在运行时,用类型参数声明的变量的类型将是一个已关闭的构造类型(§4.4.2)。所有涉及类型参数的语句和表达式在运行时执行时都使用为该参数提供的实际类型作为类型参数。”
但在您的尝试中,TCollection将无法与此文本匹配,因为它要求一个非关闭类型。

2
也许从4.4.3开始有用:“唯一可以引用未绑定泛型类型的结构是typeof表达式(§7.6.11)。” - Mike Zboray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接