2

使用反射,我试图抓住一个类字段并填充它们。目前我让它检测一个实例Dictionary<,>并创建一个Dictionary<object,object>来填充。之后它尝试更改类型,但这不起作用并且无法转换:

// Looping through properties. Info is this isntance.
// Check is a dictionary field.
Dictionary<object, object> newDictionary = new Dictionary<object, object>();

// Populating the dictionary here from file.
Type[] args = info.PropertyType.GetGenericArguments();
info.GetSetMethod().Invoke(data, new object[]
    {
        newDictionary.ToDictionary(k => Convert.ChangeType(k.Key, args[0]),
                                   k => Convert.ChangeType(k.Value, args[1]))
    });

有任何想法吗?谢谢。

4

3 回答 3

10

您应该手动创建您找到的类型的字典。

Type dictionary = typeof(Dictionary<,>);
Type[] typeArgs = info.PropertyType.GetGenericArguments();

// Construct the type Dictionary<T1, T2>.
Type constructed = dictionary.MakeGenericType(typeArgs);
IDictionary newDictionary = (IDictionary)Activator.CreateInstance(constructed);

// Populating the dictionary here from file. insert only typed values below
newDictionary.Add(new object(), new object());


info.SetValue(data, newDictionary, null);

反对者的证明。

    static void Main(string[] args)
    {
        IDictionary<int, string> test = new Dictionary<int, string>();
        var castedDictionary = (IDictionary)test;
        castedDictionary.Add(1, "hello");
        Console.Write(test.FirstOrDefault().Key);
        Console.Write(test.FirstOrDefault().Value);
        Console.ReadLine();
    }

Dictionary<TKey, TValue>实现IDictionary,在我的示例中,我正在创建Dictionary<TKey, TValue> ( Type dictionary = typeof(Dictionary<,>);) 的实例。

public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
    ICollection<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, 
    IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, 
    IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, ISerializable, 
    IDeserializationCallback
于 2012-08-23T15:46:22.377 回答
0

可能已经晚了,但我确实遇到了这个问题。user854301 是绝对正确的。我需要它在运行时传递一个通用字典,我已经弄清楚了大部分,只是缺少 IDictionary。第一次没有用,因为我犯了和 Fyodor Soikin 一样的错误;寻找IDictionary<T,U>。然而,魔法在System.Collections.IDictionary而不是System.Collections.Generic.IDictionary<>

Type[] types = prop.PropertyType.GetGenericArguments();
Type dictType = typeof(Dictionary<,>).MakeGenericType(types);
IDictionary dict = (IDictionary)Activator.CreateInstance(dictType);
types.Dump();
dictType.GetGenericArguments().Dump();
dict.GetType().GetGenericArguments().Dump();
array.Split(';').ForEach(a =>
{
    dict.Add(MyFunctions.ChangeType(a.Split(',')[0], types[0]), MyFunctions.ChangeType(a.Split(',')[1], types[1]));
}); // List Items
dict.GetType().GetGenericArguments().Dump();
prop.SetValue(newT, dict);
于 2021-01-14T01:28:03.837 回答
-1

创建一个辅助泛型类,它可以执行您需要执行的任何操作并生成正确键入的结果。然后根据运行时已知的类型动态实例化该类。

interface IHelper
{
    object CreateDictionary ();
}

class Helper<TKey, TValue> : IHelper
{
    public object CreateDictionary ()
    {
        return (whatever).ToDictionary<TKey, TValue>( blah );
    } 
}

var h = Activator.CreateInstance( typeof( Helper<,> ).MakeGenericType( yourKnownKeyType, yourKnownValueType ) ) as IHelper;
info.SetValue( h.CreateDictionary() );

如果这种情况经常发生,您还应该缓存帮助程序实例以避免每次动态实例化的影响。

于 2012-08-23T15:54:55.597 回答