C#反射字典

本文关键字:字典 反射 | 更新日期: 2023-09-27 18:21:28

说我有这个代码:

Dictionary<String, String> myDictionary = new Dictionary<String, String>();
Type[] arguments = myDictionary.GetType().GetGenericArguments();

在我的程序myDictionary中,它是未知类型的(它是从反序列化的XML返回的对象),但就本问题而言,它们是字符串。我想创建这样的东西:

Dictionary<arguments[0],arguments[1]> mySecondDictionary = new Dictionary<arguments[0],arguments[1]>();

显然,它不起作用。我在MSDN上搜索了一下,发现他们在使用Activator类,但我不明白。也许有更高级的人可以帮我一点忙。

C#反射字典

您可以使用前面提到的activator类来从给定类型创建对象。MakeGenericType方法允许您指定一个Types数组作为泛型对象的参数,这正是您试图模拟的。

Dictionary<String, String> myDictionary = new Dictionary<String, String>();
Type[] arguments = myDictionary.GetType().GetGenericArguments();
Type dictToCreate = typeof(Dictionary<,>).MakeGenericType(arguments);
var mySecondDictionary = Activator.CreateInstance(dictToCreate);

上面的代码基本上没有意义,因为您知道字典事先是String,String,但假设您在运行时有一种方法可以在其他地方检测所需的类型,那么您可以使用最后两行来实例化该类型的字典。

这种方法存在问题。我会尽力解释的。我编写了一个程序,该程序首先将类序列化为XML,然后将其反序列化。基本上,类是一个泛型类,它包含一个List(与类的类型相同)。因此,类的类型可以是任何类型,从简单的类型(如string、int等)到更复杂的类(如book类或person)。在使用XmlSerializer.Deserialize方法并获取对象之后,我应该使用Reflection重新构造回对象并访问列表。我不能那样做。所以,如果我有这样的东西:

Type classToCreate = typeof(classToBeSerialized<>).MakeGenericType(arguments);
var reconstructedClass = Activator.CreateInstance(classToCreate);

其中classToBeSerialized是假定的类(它有我提到的列表),returnedObject是从XmlSerializer返回的对象。反序列化,我想访问如下列表:

 ((reconstructedClass)returnedObject).lista

基本上,我使用反射将对象投射到它的源。

我知道这是一个旧线程,但我只是需要一些类似的东西,并决定展示它(你知道谷歌)。

这基本上是@user2536272 对答案的重写

public object ConstructDictionary(Type KeyType, Type ValueType)
{
    Type[] TemplateTypes = new Type[]{KeyType, ValueType};
    Type DictionaryType = typeof(Dictionary<,>).MakeGenericType(TemplateTypes);
    return Activator.CreateInstance(DictionaryType);
}
public void AddToDictionary(object DictionaryObject, object KeyObject, object ValueObject )
{
    Type DictionaryType = DictionaryObject.GetType();
    if (!(DictionaryType .IsGenericType && DictionaryType .GetGenericTypeDefinition() == typeof(Dictionary<,>)))
        throw new Exception("sorry object is not a dictionary");
    Type[] TemplateTypes = DictionaryType.GetGenericArguments();
    var add = DictionaryType.GetMethod("Add", new[] { TemplateTypes[0], TemplateTypes[1] });
    add.Invoke(DictionaryObject, new object[] { KeyObject, ValueObject });
}