通用列表或不同类型的字典
我想要一个将字符串映射到不同类型的通用列表的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之间的中间地带,你应该利用IList
和dynamic
。 这是我认为更正确的:
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()); } }