C#中如何将List<dynamic>值通过反射赋值给对象的泛型List字段
适配动态列表到强类型字段的实现方案
这套方案完全保留原有遍历解析字符串、构造单元素数据的流程,仅在反射赋值环节增加一层类型适配,即可解决List<dynamic>(即List<object>)与目标强类型List的类型不匹配问题,不需要调整现有代码的核心设计。
该异常的本质原因是
List<T>不支持泛型协变,List<object>与List<int>属于完全独立的类型,即使列表内元素全部为int类型,也无法直接完成类型转换。
具体实现步骤
- 反射获取目标字段的完整类型后,先拆解出目标强类型List对应的元素泛型参数:
通过field.FieldType.GetGenericArguments()[0]即可提取出List<T>中的T类型,比如目标字段为List<int>时,即可拿到typeof(int)作为列表元素的实际类型。 - 基于提取到的元素类型,动态构造对应强类型的List实例:
利用MakeGenericType方法生成和目标字段完全匹配的List类型,不硬编码具体元素类型,可适配任意元素类型的列表场景,核心参考代码如下:// 提取目标List的元素类型 Type elementType = targetFieldType.GetGenericArguments().First(); // 构造匹配的强类型List实际类型,例如 List<Int32> Type typedListType = typeof(List<>).MakeGenericType(elementType); // 实例化强类型List IList typedList = (IList)Activator.CreateInstance(typedListType); // 将原有动态列表的元素逐项移入强类型列表 foreach (var dynamicItem in ldy) { // 兼容值类型/基础类型的装箱转换,依托原有已验证的元素值保证类型安全 object convertedItem = Convert.ChangeType(dynamicItem, elementType); typedList.Add(convertedItem); } - 替换原有反射赋值的传参内容,直接传入构造好的强类型List实例即可完成赋值:
field.SetValue(targetObject, typedList);
注意事项
- 整个适配流程完全不改动原有核心业务逻辑,符合“不调整现有设计”的要求。
- 由于原有逻辑已经提前验证过所有动态元素的值、数据类型符合业务预期,该适配环节不会引入额外的类型校验开销,也不会出现转换错误。
- 若列表元素包含可空值类型(如
int?),仅需在Convert.ChangeType前额外判断一次元素类型是否为Nullable<T>,拆出底层的非空值类型做转换即可,无需调整核心适配流程。
内容的提问来源于stack exchange,提问作者Kornél La Varga
相关产品推荐
相关产品推荐

