为什么C#不支持嵌套泛型(带参数化类型的泛型)?

5

最近(可能是由于设计缺陷),我面临一个常规任务,需要有一个MyType<T>的集合,其中T不是固定的(即在一个集合中多个不同的泛型实例化)。

由于这种情况经常被提出,因此声明了一个抽象类:

public abstract class MyType {}
public class MyType<T>: MyType {}

然后我有一个MyType的集合。然而,对于这个集合,我有一个约束条件,即任何类型T最多只能有一个元素。
因此,我进行了一些ICollection<TBase>的自定义实现。我想在其中包括一个方法Get<TParam>(),用于获取与类型TParam相对应的项目。稍后可以像这样使用:
MyCollection<MyType> collection = new MyCollection<MyType>();
MyType<int> myInt = collection.Get<int>();

然而我意外地发现,我甚至无法声明它:

public TCustom<TParam> Get<TParam, TCustom<TParam>>() { } //this won't compile

因为C#和.NET都不支持内部泛型(或所谓的“泛型的泛型”)。你认为除了复杂性之外,是否有任何特定原因限制了这种情况? 更新1。 请求编译器版本和编译器错误。
Microsoft C#,.NET 3.5(Visual Studio 2010)。 错误:
错误CS0081:类型参数声明必须是标识符而不是类型 错误CS0246:找不到类型或命名空间名称“TCustom”(是否缺少使用指令或程序集引用?) 更新2。 问我是否需要修复或解释原因。我真的想知道为什么。但是如果您对问题有好的解决方案,也欢迎您。 更新3。 这个问题可能已经在this blog post中得到回答。看起来CLR团队承受着不过度复杂化语言的巨大压力。

1
请将以下与编程有关的内容从英语翻译成中文。只返回已翻译的文本:还请附上您获得的编译器错误。 - mtijn
这个问题只能由微软的C#团队回答。如果你很幸运,他们中的某个人会看到这个问题,但实际上这不是SO擅长处理的那种问题:你在寻求一个观点。 - Richard
你是在问为什么会有这个限制(我不太确定您的意思,因为您描述的情境很复杂),还是要询问如何解决这个问题? - Lasse V. Karlsen
Lasse,我相信没有深度重新设计是无法解决的。因此,我会感激任何好的解决方案,但我更想知道为什么微软在限制这个问题时保持沉默。 - Alec
如果您能提供一个简短但完整的代码示例来说明错误,那将非常有帮助。目前为止,我无法确定您的“TCustom”类应该是什么,因此在尝试弄清楚您究竟想要做什么时,我有点困惑。 - Jim Mischel
Jim,这种类型没有什么特殊的。TCustom <> 应该是 MyType <>。 - Alec
2个回答

1
在这种情况下,您可以简单地将数据隐藏在非泛型字典中:
private Dictionary<Type, object> _Data;

然后是你的Get方法:

public MyType<TParam> Get<TParam>()
{ 
    return (MyType<TParam>)_Data[typeof(TParam)];
}

如果 TParam 类型没有关联,那么根本就没有共同的数据结构可以给你类型安全,所以为什么要尝试呢?

一种针对较新版本的.NET的类型安全方法是使用一个静态类MyTypeDataHolder<T> where T:class,其中包含一个ConditionalWeakTable<MyType,T>。然后,MyType<TParam> Get<TParam>可以从MyTypeDataHolder<T>.table[this]获取数据。 - supercat

0

你到底为什么需要呢?

public TCustom<TParam> Get<TParam, TCustom<TParam>>() { } 

当泛型类型(在您的情况下为MyType)已知时,您不能只是这样做吗?
public MyType<TParam> Get<TParam>() { 
  return (MyType<TParam>)_items.FirstOrDefault(i => i is MyType<TParam>);
}

还有什么我没有理解吗?


Maxem,如果我正在实现ICollection<MyType>,那就没问题了。但我更倾向于实现一个通用集合,因此不想与特定类型的实例耦合。当然,我可以为MyCollection<MyType>创建一个扩展方法,并使用您提供的实现。但这有点令人沮丧,因为它消除了通用方法的优势。 - Alec
此外,我的集合实现细节(可能)比使用FirstOrDefault()更快地给我一个结果,例如当我在内部使用字典时。 - Alec

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