静态类序列化:JsonElement转目标属性类型的实现难题
静态类序列化时的类型转换问题解决方法
我在实现静态类的序列化功能时遇到了类型转换问题,原代码如下:
var properties = type.GetProperties(BindingFlags.Static | BindingFlags.Public); var dictionary = JsonSerializer.Deserialize<Dictionary<string, object>>(File.ReadAllText(filePath)); foreach (var property in properties) { property.SetValue(null, dictionary[property.Name]); }
运行时抛出异常:
System.ArgumentException: 'Object of type 'System.Text.Json.JsonElement' cannot be converted to type 'System.String'.'
我曾尝试遍历字典值并转换类型,但未解决问题,尝试的代码如下:
foreach (var property in properties) { var value = (JsonElement)dictionary[property.Name]; var json = value.GetRawText(); JsonSerializer.Deserialize<object>(json); }
解决方法
问题根源是用Dictionary<string, object>反序列化时,System.Text.Json会将无法直接映射的类型存储为JsonElement,直接赋值给静态属性会因类型不匹配报错。正确做法是针对每个属性的目标类型,将JsonElement反序列化为对应类型:
优化后的核心代码
var properties = type.GetProperties(BindingFlags.Static | BindingFlags.Public); // 直接反序列化为JsonElement字典,避免不必要的装箱操作 var dictionary = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(File.ReadAllText(filePath)); foreach (var property in properties) { if (dictionary.TryGetValue(property.Name, out var jsonElement)) { // 根据属性类型直接反序列化JsonElement var convertedValue = jsonElement.Deserialize(property.PropertyType); property.SetValue(null, convertedValue); } }
带异常处理的健壮版本
如果需要处理键不存在或类型转换失败的情况,可以添加额外判断:
var properties = type.GetProperties(BindingFlags.Static | BindingFlags.Public); var dictionary = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(File.ReadAllText(filePath)); foreach (var property in properties) { if (!dictionary.TryGetValue(property.Name, out var jsonElement)) { Console.WriteLine($"未找到属性 {property.Name} 对应的值"); continue; } try { var convertedValue = jsonElement.Deserialize(property.PropertyType); property.SetValue(null, convertedValue); } catch (JsonException ex) { Console.WriteLine($"转换属性 {property.Name} 失败: {ex.Message}"); } }
关键说明
- 将字典类型改为
Dictionary<string, JsonElement>,直接获取原始的JSON元素,避免object类型带来的装箱和类型转换问题。 - 利用
JsonElement.Deserialize(Type)方法,根据静态属性的PropertyType精准转换类型,确保赋值时类型匹配。
内容的提问来源于stack exchange,提问作者AXOLOTsh
相关产品推荐
相关产品推荐

