You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Newtonsoft.Json仅序列化字段而非属性(不修改类库)

解决定点数库对象仅序列化指定字段且避免循环引用的方案

针对你不能修改定点数库源码、仅需序列化x/y字段并解决循环引用的需求,以下是两种主流JSON序列化库的实现方案:

Newtonsoft.Json(Json.NET)方案

通过自定义ContractResolver过滤要序列化的成员,完全无需修改库文件:

public class FixedPointContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        // 仅保留公共实例字段中的x和y
        return type.GetFields(BindingFlags.Public | BindingFlags.Instance)
                   .Where(field => field.Name is "x" or "y")
                   .Select(field => CreateProperty(field, memberSerialization))
                   .ToList();
    }
}

使用时配置序列化设置:

var serializerSettings = new JsonSerializerSettings
{
    ContractResolver = new FixedPointContractResolver(),
    // 额外开启循环引用忽略,防止漏网的引用问题
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};

string serializedJson = JsonConvert.SerializeObject(yourFixedPointInstance, serializerSettings);

System.Text.Json 方案

通过自定义JsonConverter精确控制序列化内容:

public class FixedPointConverter : JsonConverter<YourFixedPointType>
{
    public override YourFixedPointType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 实现反序列化逻辑,按需读取x和y字段
        using var jsonDoc = JsonDocument.ParseValue(ref reader);
        var root = jsonDoc.RootElement;
        
        var instance = new YourFixedPointType();
        if (root.TryGetProperty("x", out var xElement))
            instance.x = JsonSerializer.Deserialize<fp>(xElement.GetRawText(), options);
        if (root.TryGetProperty("y", out var yElement))
            instance.y = JsonSerializer.Deserialize<fp>(yElement.GetRawText(), options);
        
        return instance;
    }

    public override void Write(Utf8JsonWriter writer, YourFixedPointType value, JsonSerializerOptions options)
    {
        // 仅序列化x和y字段
        writer.WriteStartObject();
        writer.WritePropertyName("x");
        JsonSerializer.Serialize(writer, value.x, options);
        writer.WritePropertyName("y");
        JsonSerializer.Serialize(writer, value.y, options);
        writer.WriteEndObject();
    }
}

配置并使用序列化器:

var serializerOptions = new JsonSerializerOptions();
serializerOptions.Converters.Add(new FixedPointConverter());
// 开启循环引用忽略增强容错性
serializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;

string serializedJson = JsonSerializer.Serialize(yourFixedPointInstance, serializerOptions);

注意事项

  • 两种方案均无需修改定点数库源码,后续库版本更新不会影响配置逻辑
  • 循环引用忽略配置作为额外保障,配合字段过滤可彻底解决之前的序列化错误

内容的提问来源于stack exchange,提问作者frostymm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 19:15:13