如果我们在编译时不知道类型参数,如何使用反射设置字典?

问题描述 投票:0回答:2

我们有一个未知类的字典,

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.Object]" is not of type "System.Collections.Generic.List
1[System.Int32]”不能在此通用集合中使用。

c# reflection
2个回答
0
投票

您有

var values = new List<object>();
,因此
values[i]
是一个
object
类型对象,无法将其插入到
Dictionary<TKey, TValue>
(其中
TValue
List
)中。

您必须将

values[i]
更改为
List
类型对象。尝试查看
Convert.ChangeType
并看看是否可行(但该对象必须实现
IConvertible
)。

顺便说一句,我同意JonasH在该问题的评论中所说的;反射可以是越来越多的反射的递归洞,以“解决”反射问题,因此您可能需要考虑这是否是一个 XY 问题


0
投票

例如,具有类型和值

// 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"
};

你可以

  1. 创建字典类型
  2. 创建字典实例
  3. 数据
  4. 填充字典
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];
© www.soinside.com 2019 - 2024. All rights reserved.