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

Protobuf-net 3:布尔属性反序列化后值异常求助

Protobuf-net 反序列化后布尔属性值被默认值覆盖的解决办法

问题原因

Protobuf的核心设计规则是默认值字段不会被序列化,而protobuf原生布尔类型的默认值是false。你的User类中IsSuperUser默认值设为true,当你将该属性赋值为false时,这个值等于protobuf的原生默认值,序列化时该字段不会被写入数据流。反序列化时,protobuf-net会自动用类定义的默认值true填充这个未被序列化的字段,导致属性值被覆盖。

解决方案

1. 用[DefaultValue]显式标记属性默认值

给IsSuperUser添加DefaultValueAttribute,明确告诉protobuf-net该属性的默认值是true。这样当属性值为false时(与标记的默认值不符),就会被正常序列化:

using System.ComponentModel;

public class User
{
    public string Name { get; set; }

    [DefaultValue(true)]
    public bool IsSuperUser { get; set; } = true;
}

2. 标记字段为必填(不推荐)

通过[ProtoMember]的IsRequired参数强制序列化该字段,即使值等于默认值。但这种方式违背了protobuf“默认值不序列化”的设计初衷,会增加序列化后的 payload 体积:

using ProtoBuf;

[ProtoContract]
public class User
{
    [ProtoMember(1)]
    public string Name { get; set; }

    [ProtoMember(2, IsRequired = true)]
    public bool IsSuperUser { get; set; } = true;
}

3. 改用可空布尔类型

如果业务逻辑允许,将IsSuperUser改为bool?(可空布尔类型)。此时null是该类型的默认值,当你赋值为false时,值不等于默认值,会被正常序列化,反序列化后也能保留false:

public class User
{
    public string Name { get; set; }
    public bool? IsSuperUser { get; set; } = true;
}

验证修改

调整代码后重新执行序列化和反序列化操作,IsSuperUser属性将保持你设置的false值,不会被默认值覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:22:48