通用列表或不同类型的字典

我想要一个将字符串映射到不同类型的通用列表的Dictionary。 即以下列forms:

 核心价值
 string List 
 string List 
 string List 
 string List 
 ...

目前我正在使用Dictionary ,然后从每个字典KeyValuePair pair条目中提取强类型列表,如下所示:

 Type layerType = pair.Value.GetType().GetGenericArguments()[0]; List objectsClicked = pair.Value as List; 

有没有更好的方法来做到这一点?

[编辑]正如已经注意到的,上面的内容没有编译,道歉 – 这就是当你在做某些事情的同时提出问题时所得到的。 更多解释。 我正在制作一个基本的空间数据查看器。 最终视图由一组Layer 。 每个图层都提供一个委托来呈现其类型(给定偏移量和比例)以及检查其当前窗口中哪些对象的方法。 对于命中测试,我希望每个图层的列表都被命中了。 该列表将是Point层的List等等……来自所有Layer的命中的分组将是强类型列表的集合。

假设你在C#4上Dictionary如何使用Dictionary

 Dictionary Dict = new Dictionary(); Dict.Add("int", new List()); Dict.Add("string", new List()); Dict["int"].Add(12); Dict["string"].Add("str"); foreach (KeyValuePair pair in Dict) { Type T = pair.Value.GetType(); Console.WriteLine(T.GetGenericArguments()[0].ToString()); } 

打印出来

System.Int32

System.String

这就是你要找的东西吗?

使用Dictionary可能只是解决方案。 但是你的代码是错的,你不能使用这样的generics。 你不能像这样创建动态类型。

您需要的一般问题是它与C#等强类型语言不兼容。 在强类型语言中,您必须知道什么类型是完全类型。 但是不能用正常手段来完成。 你对generics的理解也是错误的。 它只是该类型的编译时扩展。

一般的想法 :在你的情况下,使用你保存在那些列表中的某种类型的OOP层次结构。 这将是更好,更安全的想法,并不会让每个看着你的代码的人撕掉他的头发。

我将采取Euphoric和Adam之间的中间地带,你应该利用IListdynamic 。 这是我认为更正确的:

 var dict = new Dictionary(); dict.Add("u", new List()); dict.Add("v", new List()); // in case of members you know they exist on an IList dict["u"].Add(new U()); dict["v"].Add(new V()); // in case you know what you are going to get back, in which case you should cast var uProperty = (dict["u"][0] as U).UProperty var vProperty = (dict["v"][0] as V).VProperty // in case your're not sure of (dict[someKey] as dynamic)[someIndex].SomeMember...; 

所有这些都比依靠reflection简单得多。 基本思想是将字典值类型声明为IList以使您的意图更清晰,同时利用dynamic来缓解reflection怪异并使代码更短。

我实际上认为更简洁的方法是为您的字典创建一个包装器:

 public class GlobalStore { private readonly IDictionary _globalStore; public GlobalStore() { _globalStore = new ConcurrentDictionary(); } public IEnumerable GetFromCache() where T : class { return (IEnumerable) _globalStore[typeof(T)]; } public void SetCache(IEnumerable cache) where T : class { _globalStore[typeof(T)] = cache; } } 

这是对它的测试:

 [TestClass] public class GlobalStoreTest { [TestMethod] public void GlobalStore_Test() { //Arrange var globalStore = new GlobalStore(); globalStore.SetCache(new List { new ClientModel { ClientId = 1, ClientName = "Client1" }, new ClientModel { ClientId = 2, ClientName = "Client2" } }); //Act var clients = globalStore.GetFromCache(); //Assert Assert.AreEqual(2, clients.Count()); } }