如何根据类中属性的类型动态创建C#泛型字典

本文关键字:创建 动态 泛型 字典 类型 何根 属性 | 更新日期: 2023-09-27 18:20:43

我正试图根据以下类中的属性类型动态创建一个通用字典:

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

让我们假设Stats属性的System.Type被分配给变量"propertyType",并且如果该类型是泛型字典,则IsGenericDictionary方法返回true。然后,我使用Activator.CreateInstance动态创建一个相同类型的通用Dictionary实例:

// 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);

这可能吗?

如何根据类中属性的类型动态创建C#泛型字典

如果要做到这一点,您必须使用反射或dynamic来切换到泛型方法,并使用泛型类型参数。否则,您必须使用object。就我个人而言,我只想在这里使用非通用IDictionary API:

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

它允许您访问数据,以及您在字典上期望的所有常用方法(但是:使用object)。转向通用方法是一种痛苦;要做到这一点,4.0之前需要反思,特别是MakeGenericMethodInvoke。然而,你可以在4.0中使用dynamic:作弊

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

带有:

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