如何让自定义SerializedField属性自动包含JsonProperty特性?
实现自定义特性自动替代[JsonProperty]的方案
如果你用的是Newtonsoft.Json(Json.NET),完全可以实现这个需求,核心是通过自定义ContractResolver来识别你的SerializedFieldAttribute,让标记了该特性的字段自动具备Json序列化能力。
步骤1:保留你的自定义特性
基础特性无需大改,保持原样即可:
public class SerializedFieldAttribute : Attribute { }
如果需要支持自定义JSON字段名(类似[JsonProperty("collider_type")]的效果),可以给特性扩展属性:
public class SerializedFieldAttribute : Attribute { public string PropertyName { get; set; } }
步骤2:自定义ContractResolver
创建继承自DefaultContractResolver的解析器,重写CreateProperty方法,让它识别你的自定义特性并处理序列化规则:
public class SerializedFieldContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); // 检查当前成员是否标记了SerializedFieldAttribute var serializedFieldAttr = member.GetCustomAttribute<SerializedFieldAttribute>(); if (serializedFieldAttr != null) { // 取消忽略该字段,允许序列化 property.Ignored = false; // 确保私有字段可读可写(默认私有字段不会被序列化) property.Readable = true; property.Writable = true; // 如果特性指定了自定义名称,就用这个名称 if (!string.IsNullOrEmpty(serializedFieldAttr.PropertyName)) { property.PropertyName = serializedFieldAttr.PropertyName; } } return property; } }
步骤3:使用自定义解析器进行序列化
在序列化/反序列化时,把自定义解析器传入JsonSerializerSettings:
// 配置序列化设置 var jsonSettings = new JsonSerializerSettings { ContractResolver = new SerializedFieldContractResolver(), Formatting = Formatting.Indented // 可选,格式化输出JSON }; // 序列化示例 var yourObject = new YourClass(); string jsonString = JsonConvert.SerializeObject(yourObject, jsonSettings); // 反序列化示例 YourClass deserializedObject = JsonConvert.DeserializeObject<YourClass>(jsonString, jsonSettings);
效果验证
现在你只需要给私有字段标记[SerializedField],就能自动实现Json序列化:
public class YourClass { [SerializedField] // 等效于标记了[JsonProperty] private int colliderType = 0; // 如果用扩展后的特性,还可以自定义字段名 [SerializedField(PropertyName = "player_name")] private string playerName = "Unknown"; }
原理说明
Newtonsoft.Json的序列化逻辑完全由ContractResolver控制,默认的DefaultContractResolver只会序列化公共成员或标记了[JsonProperty]的私有成员。我们的自定义解析器通过检查字段是否存在SerializedFieldAttribute,强制开启该字段的序列化权限,达到和直接标记[JsonProperty]相同的效果。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

