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

Protobuf.net序列化实现IEnumerable<T>的ObservableList类失败问题

Protobuf.net序列化实现IEnumerable的自定义类时属性丢失问题

问题场景

尝试使用最新版Protobuf.net序列化自定义ObservableList<T>类(实现IEnumerable<T>接口),类定义如下:

[ProtoContract(SkipConstructor = true)]
public class ObservableList<T> : IEnumerable<T>
{
    [ProtoMember(1)] private List<T> _list = new();
    [ProtoMember(2)] private string _code;
    [ProtoMember(3)] private int _version;

    public string Code
    {
        get => _code;
        set => _code = value;
    }

    public int Version
    {
        get => _version;
        set => _version = value;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return _list.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

执行测试时发现反序列化后Code属性为null,测试代码如下:

[Test]
public void Test1()
{
    var list = new ObservableList<string>();
    list.Code = "FK1";
    list.Version = 22;

    var ms = new MemoryStream();
    ProtoBuf.Serializer.Serialize(ms, list);
    ms.Position = 0;
    var deserialized = ProtoBuf.Serializer.Deserialize<ObservableList<string>>(ms);

    Assert.AreEqual("FK1", deserialized.Code); // 此处失败,Code为null
    Assert.AreEqual(22, deserialized.Version);
}

移除IEnumerable<T>接口后序列化恢复正常,需要排查原因并解决。

问题原因

Protobuf.net对实现IEnumerable<T>接口的类型有特殊处理逻辑:默认会将这类类型识别为集合类型,序列化时优先处理集合元素(即示例中的_list字段),同时自动忽略其他非集合相关的字段(_code、_version),导致这些属性在反序列化后无法正确恢复。

解决方法

方案1:禁用集合自动处理(推荐)

在[ProtoContract]特性中添加IgnoreListHandling = true参数,明确告诉Protobuf.net不要将该类当作集合类型处理,而是按普通类序列化所有标记了[ProtoMember]的字段:

[ProtoContract(SkipConstructor = true, IgnoreListHandling = true)]
public class ObservableList<T> : IEnumerable<T>
{
    // 原有代码保持不变
}

修改后重新执行测试,Code和Version属性都能正确序列化和反序列化。

方案2:调整序列化配置(备选)

如果无法修改类的特性,可以在序列化时通过RuntimeTypeModel手动配置,禁用该类型的集合处理:

RuntimeTypeModel.Default.Add(typeof(ObservableList<string>), false)
    .SetIgnoreListHandling(true);

这种方式适合无法修改类源码的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:04:54