我们有一个未知类的字典,
Dictionary<TKey, TValue> MyDictionary
并且我们有使用反射获得的FieldInfo
对象。我们还有在运行时获取的类型参数 Type keyType = typeof(TKey)
和 Type valueType = typeof(TValue)
。
键值对存在于两个单独的列表中
List<object> keys
和 List<object> values
。
我们如何生成字典并使用
FieldInfo.SetValue()
设置其值?
到目前为止,我们尝试过:
var dictionary = Activator.CreateInstance(fieldInfo.FieldType);
var keys = new List<object>();
var values = new List<object>();
// Code to set keys and values
for (int i = 0; i < keys.Count; i++)
(dictionary as IDictionary).Add(keys[i], values[i]);
fieldInfo.SetValue(mainObj, dictionary);
在
TValue
为 List<int>
的特定情况下,add 语句会抛出异常
System.ArgumentException:'值“System.Collections.Generic.List
1[System.Int32]”不能在此通用集合中使用。1[System.Object]" is not of type "System.Collections.Generic.List
您有
var values = new List<object>();
,因此 values[i]
是一个 object
类型对象,无法将其插入到 Dictionary<TKey, TValue>
(其中 TValue
是 List
)中。
您必须将
values[i]
更改为 List
类型对象。尝试查看 Convert.ChangeType
并看看是否可行(但该对象必须实现 IConvertible
)。
顺便说一句,我同意JonasH在该问题的评论中所说的;反射可以是越来越多的反射的递归洞,以“解决”反射问题,因此您可能需要考虑这是否是一个 XY 问题。
例如,具有类型和值
// Let me use predefined types;
// You can obtain required types from FieldInfo
Type keyType = typeof(int);
Type valueType = typeof(string);
List<object> keys = new () {
4, 5, 6
};
List<object> values = new () {
"four", "five", "six"
};
你可以
var dictType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
var dictionary = Activator.CreateInstance(dictType);
for (int i = 0; i < keys.Count; ++i)
(dictionary as System.Collections.IDictionary).Add(keys[i], values[i]);
我们来看看:
// Dictionary Type
Console.WriteLine(dictionary.GetType());
// Values
Console.WriteLine(string.Join(Environment.NewLine,
(dictionary as IDictionary<int, string>)));
输出:
System.Collections.Generic.Dictionary`2[System.Int32,System.String]
[4, four]
[5, five]
[6, six]
编辑:从
unknownDictionary
获取键和值类型:
object unknownDictionary = new Dictionary<int, string>();
...
Type keyType = unknownDictionary.GetType().GenericTypeArguments[0];
Type valueType = unknownDictionary.GetType().GenericTypeArguments[1];