5

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

由于它被广泛提议(对于这种情况),声明了一个抽象类:

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

然后我有一个集合MyType。但是对于这个集合,我有一个限制,即任何类型的元素都不能超过一个T

因此,我对ICollection<TBase>. 我想在其中包含一种Get<TParam>()获取与 type 对应的项目的方法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”(您是否缺少 using 指令或程序集引用?)

更新 2.询问我是否需要修复或解释原因。我真的很想知道为什么。但是,如果您对问题有很好的解决方案,也欢迎您。

更新 3.这个问题可能已经在这篇博文中得到了回答。看起来 CLR 团队承受着很大的压力,不能让语言过于复杂。

4

2 回答 2

1

在这种情况下,您可以简单地将数据隐藏在非通用字典中:

private Dictionary<Type, object> _Data;

然后你的Get方法:

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

如果TParam类型不相关,那么无论如何都没有通用的数据结构可以为您提供类型安全,那么为什么还要尝试呢?

于 2011-10-07T10:19:31.937 回答
0

为什么你需要

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

当泛型类型(在您的情况下为 MyType )已知时,您不能这样做

public MyType<TParam> Get<TParam>() { 
  return (MyType<TParam>)_items.FirstOrDefault(i => i is MyType<TParam>);
}

还是我错过了什么?

于 2011-10-07T09:33:29.943 回答