我正在尝试制作混合的类型集合。我知道一开始的类型..但我似乎无法弄清楚制作集合的语法等。
例如
....
// I leave the typo there, for embarrassment :(
Initialize(new []{ typeof(Cat), typeof(Dog), typeof(JohnSkeet) });
...
public Foo Initialize(IEnumerable<Type> types)
{
// for each type, set up the inmemory storage.
foreach(var type in types)
{
// ????
// Create an empty list, which will only contain this 'type'
// I'm guessing, an IDictionary<type, ICollection<type>>().. thingy ?
}
}
public ICollection<Type> SomeTypeData(Type type)
{
// Return the collection, for this type.
}
这种鬃毛有意义吗?这可能吗?
答案 0 :(得分:6)
好的,现在我觉得我知道你想要什么,它看起来像这样:
// This can't really be *properly* statically typed
private readonly Dictionary<Type, object> typeMap = new
Dictionary<Type, object>();
public Foo Initialize(IEnumerable<Type> types)
{
Type genericListType = typeof(List<>);
foreach(var type in types)
{
// MakeGenericType is really badly named
Type constructedListType = genericListType.MakeGenericType(type);
typeMap[type] = Activator.CreateInstance(constructedListType);
}
}
// We can't express this particularly safely either,
// although we *could* return the non-generic IList
public object SomeTypeData(Type type)
{
return typeMap[type];
}
// This *is* statically typed, although we need to cast inside
public IList<T> SomeTypeData<T>()
{
return (IList<T>) typeMap[typeof(T)];
}
有关类似示例,请参阅this blog post。
请注意,就内部字典类型而言,基本上你试图表示泛型根本无法处理的东西......并且SomeTypeData
的第一种形式也不能静态输入。因为这意味着在编译时知道类型,而我们只会在执行时实际给出它。
答案 1 :(得分:1)
在我看来,你正在尝试创建某种实例存储库;存储给定类型实例列表的类。
这是一个示例实现。我已经包含了SomeTypeData方法的泛型和非泛型版本:
public class InstanceRepository
{
private IDictionary<Type, ICollection> _Instances = new Dictionary<Type, ICollection>();
public ICollection SomeTypeData(Type type)
{
ICollection instanceList;
if (!_Instances.TryGetValue(type, out instanceList))
{
// this type does not exist in our dictionary, so let's create a new empty list
// we could do this:
//instanceList = new List<object>();
// but let's use reflection to make a more type-specific List<T> instance:
instanceList = (ICollection)Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
// now add it to the dictionary
_Instances.Add(type, instanceList);
}
// Return the collection, for this type.
return instanceList;
}
public IList<T> SomeTypeData<T>()
{
Type type = typeof(T);
ICollection instanceList;
if (!_Instances.TryGetValue(typeof(T), out instanceList))
{
instanceList = new List<T>();
_Instances.Add(type, instanceList);
}
// here we are assuming that all of the lists in our dictionary implement IList<T>.
// This is a pretty safe assumption, since the dictionary is private and we know that
// this class always creates List<T> objects to put into the dictionary.
return (IList<T>)instanceList;
}
}
以下是一个用法示例:
通用:
InstanceRepository repository = new InstanceRepository();
var listOfCats = repository.SomeTypeData<Cat>();
listOfCats.Add(new Cat());
Cat firstCat = listOfCats[0];
Console.WriteLine(listOfCats.GetType().FullName);
非通用:
InstanceRepository repository = new InstanceRepository();
var listOfCats = (IList<Cat>)repository.SomeTypeData(typeof(Cat));
listOfCats.Add(new Cat());
Cat firstCat = listOfCats[0];
Console.WriteLine(listOfCats.GetType().FullName);
答案 2 :(得分:0)
我不确定我是否完全理解你的问题,但是如果你已经有一个包含Type对象枚举的IEnumerable<Type>
,那么为什么不用它来初始化某种类型的Collection(例如List<Type>
)?
public ICollection<Type> Initialize(IEnumerable<Type> types)
{
ICollection<Type> collection = new List<Type>(types);
return collection;
}
答案 3 :(得分:0)
我想你想要像
这样的东西_dict[typeof(Cat)]=new List<Cat>();
_dict[typeof(Dog)]=new List<Dog>();
仅以编程方式基于给定类型? 这样的事情应该有效:
public void Initialize(IEnumerable<Type> types)
{
foreach(var type in types)
{
var list = Activator.CreateInstance(Type.GetType("System.Collections.Generic.List`1").MakeGenericType(type));
_cache[type] = list;
}
}
public ICollection<T> Get<T>()
{
object list;
if (_cache.TryGetValue(typeof(T), out list)
{
return list as ICollection<T>;
}
else
{
...
}
}
var cats = Get<Cat>();