我可以创build一个genericstypes的字典吗?

我想创build一个Dictionary对象,stringKeys,保存值是一个genericstypes。 我想它会看起来像这样:

Dictionary<string, List<T>> d = new Dictionary<string, List<T>>(); 

并让我添加以下内容:

 d.Add("Numbers", new List<int>()); d.Add("Letters", new List<string>()); 

我知道我可以做一个string列表,例如,使用这个语法:

 Dictionary<string, List<string>> d = new Dictionary<string, List<string>>(); d.Add("Key", new List<string>()); 

但是如果可能的话,我想做一个通用的列表…

那么2个问题:

  1. 可能吗?
  2. 什么语法?

非常感谢,
乔恩

编辑:现在我已经重读这个问题…

你不能这样做,但一个自定义集合可以在一定程度上处理它。 你基本上有一个通用的Add方法:

 public void Add<T>(string key, List<T> list) 

(集合本身不是通用的 – 除非你想使关键types通用。)

不过,你不能以强types的方式从中提取值,因为编译器不知道你使用哪种types的键。 如果你把关键字本身作为types,那么你的情况会稍微好一些,但是现有的集合仍然不支持。 这是我原来的答案是回应的情况。

编辑:原来的答案,当我没有正确阅读的问题,但哪些可能是翔实的反正…

不,你恐怕不能让一个types的论点取决于另一个types的论点。 这只是人们可能想要在genericstypes系统中expression的东西之一,但是.NET的约束是不允许的。 总会遇到这样的问题,.NETdevise者select保持generics相对简单。

但是,您可以编写一个集合来相当容易地执行该集合。 我在一篇只保留一个值的博客文章中有一个例子 ,但是使用列表很容易。

会这样的工作吗?

 public class GenericDictionary { private Dictionary<string, object> _dict = new Dictionary<string, object>(); public void Add<T>(string key, T value) where T : class { _dict.Add(key, value); } public T GetValue<T>(string key) where T : class { return _dict[key] as T; } } 

基本上它把所有的幕后花絮都包装在内。

我更喜欢这种将genericstypes放入集合的方式:

 interface IList { void Add (object item); } class MyList<T> : List<T>, IList { public void Add (object item) { base.Add ((T) item); // could put a type check here } } class Program { static void Main (string [] args) { SortedDictionary<int, IList> dict = new SortedDictionary<int, IList> (); dict [0] = new MyList<int> (); dict [1] = new MyList<float> (); dict [0].Add (42); dict [1].Add ("Hello"); // Fails! Type cast exception. } } 

但是你在编译时会丢失types检查。

我们使用大量的reflection来创build一个可扩展的pipe理工具。 我们需要一种在模块定义中的全局search中注册项目的方法。 每个search都会以一致的方式返回结果,但是每个search都有不同的依赖关系。 以下是我们注册search单个模块的示例:

 public void ConfigureSearch(ISearchConfiguration config) { config.AddGlobalSearchCallback<IEmploymentDataContext>((query, ctx) => { return ctx.Positions.Where(p => p.Name.Contains(query)).ToList().Select(p => new SearchResult("Positions", p.Name, p.ThumbnailUrl, new UrlContext("edit", "position", new RouteValueDictionary(new { Id = p.Id })) )); }); } 

在模块注册的后台,我们迭代每个模块,并将Func添加到一个SearchTable中,其实例为:

 public class GenericFuncCollection : IEnumerable<Tuple<Type, Type, Object>> { private List<Tuple<Type, Type, Object>> objects = new List<Tuple<Type, Type, Object>>(); /// <summary> /// Stores a list of Func of T where T is unknown at compile time. /// </summary> /// <typeparam name="T1">Type of T</typeparam> /// <typeparam name="T2">Type of the Func</typeparam> /// <param name="func">Instance of the Func</param> public void Add<T1, T2>(Object func) { objects.Add(new Tuple<Type, Type, Object>(typeof(T1), typeof(T2), func)); } public IEnumerator<Tuple<Type, Type, object>> GetEnumerator() { return objects.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return objects.GetEnumerator(); } } 

那么当我们终于打电话的时候,我们用反思来做:

 var dependency = DependencyResolver.Current.GetService(search.Item1); var methodInfo = search.Item2.GetMethod("Invoke"); return (IEnumerable<SearchResult>)methodInfo.Invoke(search.Item3, new Object[] { query, dependency }); 

其他可能性是使用variablesdynamic。

例如:

Dictionary<string, List<dynamic>> d = new Dictionary<string, List<dynamic>>(); d.Add("Key", new List<dynamic>());

variablesdynamicparsing运行时的types。

我没有find我在这里寻找的东西,但是在阅读之后,我想这可能是被要求的,所以试图回答。

问题是,当你使用Dictionary时,它是一个封闭的构造types,所有的元素都必须是TValuetypes。 我在很多地方看到这个问题没有一个好的答案。

事实是,我想索引,但每个元素有不同的types,并基于TKey的价值,我们已经知道types。 不试图绕过拳击,但试图简单地获得像DataSetExtensions字段更优雅的访问。 而不想使用dynamic,因为types是已知的,它只是不想要的。

一个解决scheme可以是创build一个非genericstypes,它不会在类级别暴露T,从而导致字典的TValue部分被closures构造。 然后撒上stream利的方法来帮助初始化。

 public class GenericObject { private object value; public T GetValue<T>() { return (T)value; } public void SetValue<T>(T value) { this.value = value; } public GenericObject WithValue<T>(T value) { this.value = value; return this; } } class Program { static void Main(string[] args) { Dictionary<string, GenericObject> dict = new Dictionary<string, GenericObject>(); dict["mystring"] = new GenericObject().WithValue<string>("Hello World"); dict["myint"] = new GenericObject().WithValue<int>(1); int i = dict["myint"].GetValue<int>(); string s = dict["mystring"].GetValue<string>(); } } 

其中一种方法是创build一个types为“object”的Dictionary值,如下所示:

Dictionary<string, object> d = new Dictionary<string, object>();

所以,这里的对象数据types被用作一个通用的数据types,你可以把任何东西都当作一个值。

假如你使用C#4,那么怎么样呢?

 Dictionary<string, dynamic> Dict = new Dictionary<string, dynamic>(); 

资料来源: https : //stackoverflow.com/a/5038029/3270733