C#反射字典

4

假设我有以下代码:

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 类,但我不明白。 也许有更高级的人可以帮我一点。

1
请为您的问题起一个有意义的标题,不要只列出标签。这样做没有意义,也不能吸引用户查看并尝试帮助您。 - abatishchev
关于你最近被移除的问题,只是备注一下。 [一切都已经被发明了](http://en.wikipedia.org/wiki/Charles_Holland_Duell) - crthompson
3个回答

1

我知道这是一个旧帖子,但我需要类似的东西,并决定展示它(你知道,为了谷歌)。

基本上,这是对@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 });
}

寻找这个解决方案已经很久了。现在运行得非常好。 - Michael

1
你可以像你提到的那样使用激活器类来创建给定类型的对象。MakeGenericType 方法允许您将类型数组指定为泛型对象的参数,这就是您试图模拟的内容。
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,但是假设您在运行时有一种检测所需类型的方法,您可以使用最后两行来实例化该类型的字典。

1
这种方法存在问题。我会尽力解释一下。我写了一个程序,首先将一个类序列化为XML,然后再将其反序列化回来。基本上,这个类是一个通用的类,它包含一个List(与类相同的类型)。因此,类的类型可以是任何东西,从简单类型(如字符串、整数等)到更复杂的类,例如书籍类或人员类。在使用XmlSerializer.Deserialize方法并获取对象之后,我应该使用Reflection来重建对象并访问列表。但我无法这样做。所以,如果我有像这样的东西:
Type classToCreate = typeof(classToBeSerialized<>).MakeGenericType(arguments);
var reconstructedClass = Activator.CreateInstance(classToCreate);

classToBeSerialized是指包含所述列表的预期类,returnedObject是从XmlSerializer.Deserialize返回的对象,我想像这样访问列表:

 ((reconstructedClass)returnedObject).lista

基本上,我正在使用反射将对象转换为其源。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接