2012-01-18 90 views
3

我试图动态地创建基于属性在下面的类类型的通用词典:如何基于类中属性的类型动态创建C#通用字典?

public class StatsModel 
{ 
    public Dictionary<string, int> Stats { get; set; } 
} 

假设属性分配给一个变量“属性类型”,而且统计的的System.Type如果类型是通用字典,则IsGenericDictionary方法返回true。然后我用Activator.CreateInstance动态地创建同一类型的通用词典如:

// Note: property is a System.Reflection.PropertyInfo 
Type propertyType = property.PropertyType; 
if (IsGenericDictionary(propertyType)) 
{ 
    object dictionary = Activator.CreateInstance(propertyType); 
} 

因为我已经知道了创建的对象是通用字典,我想转换为通用字典,它的类型参数等于属性类型的一般参数:

Type[] genericArguments = propertyType.GetGenericArguments(); 
// genericArguments contains two Types: System.String and System.Int32 
Dictionary<?, ?> = (Dictionary<?, ?>)Activator.CreateInstance(propertyType); 

这可能吗?

回答

5

如果你想这样做,你必须使用反射或dynamic来翻转成一个通用的方法,并使用泛型类型参数。没有这个,你必须使用object。就个人而言,我只是使用非通用IDictionary API这里:

// we know it is a dictionary of some kind 
var data = (IDictionary)Activator.CreateInstance(propertyType); 

,让你访问的数据,和所有常见的方法,您希望在一本字典(但:使用object)。转变为一种通用的方法是一种痛苦;要做到4.0之前需要反思 - 具体是MakeGenericMethodInvoke。你可以,但是,使用dynamic骗取4.0:

dynamic dictionary = Activator.CreateInstance(propertyType); 
HackyHacky(dictionary); 

有:

void HackyHacky<TKey,TValue>(Dictionary<TKey, TValue> data) { 
    TKey ... 
    TValue ... 
} 
+0

访问常用的字典方法就是我一直在寻找。我会投向IDictionary,特别是因为我不喜欢黑客;-)非常感谢Marc! – Jeroen 2012-01-18 13:39:19

+0

我得到:泛型类型'System.Collections.Generic.IDictionary '需要2个类型参数 – tdc 2013-05-09 10:01:33

+1

@tdc在代码文件顶部添加一个'using System.Collections;'指令 – 2013-05-09 10:03:48