泛型列表反序列化时类型转换异常的解决求助
泛型列表反序列化时类型转换异常的解决求助
兄弟,我太懂你这糟心的问题了!你现在遇到的核心问题是**List<object>和List<int>是完全不同的泛型类型**,哪怕你把每个元素都转成int塞进List<object>里,也没法直接赋值给List<int>的字段,所以才会抛出那个类型转换异常。
给你几个实用的解决办法,按需选就行:
方法一:直接指定类型反序列化(最简单高效)
如果已经明确知道字段是List<int>,直接用JsonConvert.DeserializeObject指定目标类型就行,完全不用手动遍历JToken:
string json = "[1,2,3,4,5,6,7,8,9,10]"; Car car = new Car(); // 一步到位把JSON转成List<int>赋值给字段 car.priceList = JsonConvert.DeserializeObject<List<int>>(json);
方法二:反射通用处理(适合不知道字段具体类型的场景)
要是你需要通用处理多个不同泛型类型的List字段,那就通过反射获取字段的泛型参数,再动态调用反序列化方法:
string json = "[1,2,3,4,5,6,7,8,9,10]"; Car car = new Car(); FieldInfo[] fieldInfos = car.GetType().GetFields(); foreach (FieldInfo fieldInfo in fieldInfos) { // 判断当前字段是不是泛型List类型 if (fieldInfo.FieldType.IsGenericType && fieldInfo.FieldType.GetGenericTypeDefinition() == typeof(List<>)) { // 获取List的泛型参数类型(比如这里就是int) Type genericElementType = fieldInfo.FieldType.GetGenericArguments()[0]; // 调用JsonConvert的反序列化方法,指定目标字段的类型 MethodInfo deserializeMethod = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); object targetList = deserializeMethod.Invoke(null, new object[] { json, fieldInfo.FieldType }); // 给字段赋值 fieldInfo.SetValue(car, targetList); } }
方法三:改进你原来的遍历代码(适合一定要手动处理元素的场景)
如果你坚持要用自己遍历JToken的方式,最后记得把List<object>转换成对应的泛型List:
string json = "[1,2,3,4,5,6,7,8,9,10]"; JArray o = (JArray)JsonConvert.DeserializeObject(json); List<object?> list = new(); foreach (JToken jToken in o) { list.Add(jToken.ToObject(typeof(int))); } Car car = new Car(); FieldInfo[] fieldInfos = car.GetType().GetFields(); foreach (FieldInfo fieldInfo in fieldInfos) { // 把List<object>转换成字段对应的泛型List Type targetListType = fieldInfo.FieldType; Type elementType = targetListType.GetGenericArguments()[0]; // 用Cast和ToList转换类型 MethodInfo castMethod = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(elementType); MethodInfo toListMethod = typeof(Enumerable).GetMethod("ToList").MakeGenericMethod(elementType); object targetList = toListMethod.Invoke(null, new[] { castMethod.Invoke(null, new[] { list }) }); fieldInfo.SetValue(car, targetList); }
最后给你补个知识点:为啥原来的代码会报错?泛型List<T>是不变类型,哪怕int是object的子类,List<int>也不能被当成List<object>用,这是C#泛型的类型安全机制决定的,所以直接赋值肯定会炸~
备注:内容来源于stack exchange,提问作者Len boy
相关产品推荐
相关产品推荐

