【问题标题】:How to create a C# generic dictionary dynamically based on the type of a property in a class?如何根据类中属性的类型动态创建 C# 泛型字典?
【发布时间】:2012-01-18 09:39:26
【问题描述】:

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

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# .net generics dictionary


    【解决方案1】:

    如果你想这样做,你必须使用反射或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 ...
    }
    

    【讨论】:

    • 访问常用的字典方法是我一直在寻找的。我将投给 IDictionary,特别是因为我不喜欢黑客 ;-) 非常感谢 Marc!
    • 我明白了:泛型类型 'System.Collections.Generic.IDictionary' 需要 2 个类型参数
    • @tdc 在代码文件的顶部添加 using System.Collections; 指令
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多