重构Dictionary.Value安全访问方法技术咨询(JSON转业务对象场景)
重构Dictionary<string, string>的安全访问逻辑方案
嘿,我刚好处理过类似的场景——9000条数据量不算小,既要保证访问Dictionary值时不抛异常,又要尽量减少冗余代码,给你几个实用的解决方案:
1. 基础安全方案:用TryGetValue替代直接索引
直接写item["Key"]很容易触发KeyNotFoundException,换成TryGetValue是最稳妥的基础写法,完全避免键不存在的异常:
foreach (var item in values) { var temp = new BuissnessObject(); if (item.TryGetValue("Id", out var idString)) { temp.Id = idString; // 如果需要转类型,比如int,这里可以加int.TryParse(idString, out var id)再赋值 } // 其他字段依葫芦画瓢 if (item.TryGetValue("Name", out var nameString)) { temp.Name = nameString; } // ... 处理address1、city、postalCode等字段 }
这种写法性能也不错,TryGetValue是字典的O(1)原生操作,不会额外消耗性能。
2. 进阶简化:封装Dictionary扩展方法
因为要处理大量重复的字段取值逻辑,写个扩展方法能大幅减少冗余代码,让映射逻辑更清爽:
先写扩展类:
public static class DictionarySafeAccessExtensions { // 基础字符串版本,默认返回空字符串 public static string GetValueOrDefault(this Dictionary<string, string> dict, string key, string defaultValue = "") { return dict.TryGetValue(key, out var value) ? value : defaultValue; } // 泛型版本,支持类型转换(比如转int、DateTime等) public static T GetValueOrDefault<T>(this Dictionary<string, string> dict, string key, T defaultValue = default) { if (dict.TryGetValue(key, out var value) && !string.IsNullOrWhiteSpace(value)) { try { return (T)Convert.ChangeType(value, typeof(T)); } catch (Exception ex) { // 这里可以加日志记录转换失败的情况,比如键名、值内容、异常信息 // 或者根据业务需求抛出特定异常 return defaultValue; } } return defaultValue; } }
然后映射的时候就可以写成简洁的对象初始化器:
foreach (var item in values) { var temp = new BuissnessObject { Id = item.GetValueOrDefault("Id"), Name = item.GetValueOrDefault("Name"), Type = item.GetValueOrDefault("Type"), Address1 = item.GetValueOrDefault("Address1"), // 如果Id是int类型,就用泛型版本: // Id = item.GetValueOrDefault<int>("Id") // ... 其他字段 }; // 处理temp对象,比如加入结果列表 }
3. 最优优化:跳过Dictionary直接反序列化业务对象
如果你的JSON结构相对稳定(即使有动态属性,也可以用Json.NET的扩展字段特性接收),其实可以直接把JSON反序列化成List<BuissnessObject>,完全绕开Dictionary的安全访问问题:
首先给业务对象加上JsonProperty特性(如果JSON键名和属性名不一致的话),动态属性用[JsonExtensionData]接收:
public class BuissnessObject { [JsonProperty("Id")] public string Id { get; set; } [JsonProperty("Name")] public string Name { get; set; } [JsonProperty("Type")] public string Type { get; set; } // ... 其他业务属性 // 用来接收JSON中未定义在类里的动态属性 [JsonExtensionData] public Dictionary<string, JToken> ExtraDynamicProperties { get; set; } }
然后直接反序列化:
var businessObjects = JsonConvert.DeserializeObject<List<BuissnessObject>>(json);
这种方式不仅代码更简洁,性能也更好——减少了中间Dictionary的转换步骤,尤其适合9000条数据的批量处理场景。
内容的提问来源于stack exchange,提问作者xdtTransform
相关产品推荐
相关产品推荐

