【发布时间】:2017-03-19 13:41:58
【问题描述】:
我有一个 Dictionary<Type, HashSet<GenericType>> 用于保存我的数据,我正在尝试创建一个函数,它返回给定泛型类型 T : GenericType 的这些 HashSet 之一。
基本上
Dictionary<Type, HashSet<GenericType>> data;
public HashSet<T> Get<T>() where T : GenericType
{
var tp = typeof(T);
//....check if its in the dictionary, fill if not....
return data[tp];
}
这当然是无效的。但我很难弄清楚我应该做什么。
我觉得返回T 是最佳选择,因为你可以这样做:
Get<Derived>().Where(x => x.DerivedProperty == someValue)
但我唯一想到的是创建一个新的HashSet<T> 每次 Get 被调用,然后使用 foreach 循环转换并从已经存在的 HashSet 中添加每个项目在字典中,但这感觉像是一种浪费?
另一个想法是跳过 HashSet 并使用另一个(协变?)集合。但由于这些集合将保存 大量 数据,因此也许这也不是最好的主意。
简而言之,我想知道解决这个问题的最佳方法是什么。
更新
这就是我得到的结构。包含data 的类型是我的代码结构中的一种服务类型。它将通过反射在运行时加载和初始化。从那里我后来使用某种 ServiceFactory 来获取该服务。
public class foo : Service
{
public Dictionary<Type, HashSet<BaseClass>> data = new Dictionary<Type, HashSet<BaseClass>>();
public T Get<T>() where T : BaseClass
{
var tp = typeof(T);
if (!data.ContainsKey(tp))
{
data.Add(typeof(Derived), new HashSet<BaseClass>() { new Derived(), new Derived(), new Derived() });
}
return data[tp];//this wont compile.
}
}
public class Derived : BaseClass
{
public int ExampleVariable {get;set;}
}
public abstract class BaseClass
{
// some things in here.
public void DoCommonStuff()
{
}
}
class program
{
static void Main(string[] args)
{
var service = ServiceFactory.GetService<foo>();
var collection = service.Get<Derived>();
}
}
【问题讨论】:
-
你需要返回一个协变接口。
-
请澄清:您获得了
Dictionary<Type, HashSet<GenericType>>,并且您已经可以从您的Dictionary中检索特定的HashSet<GenericType>,但无法从上述HashSet中检索GenericType。对吗? -
是的,我可以毫无问题地从字典中获取 HashSet。然后我有一个 HashSet
,我不能将它作为 HashSet 返回 -
@Tokfrans 你能告诉我更多的代码吗?基本上,您如何定义声明
data的类。只需从类中删除与问题无关的所有内容。因为仅仅指定类class Klass<TGenericType> : IKlass<out TGenericType> { .. }可能就足够了。 -
@SvenM。虽然我已经更新并试图解释我的情况,但我不确定你的意思。
标签: c# generics covariance contravariance